http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/main/webapp/css/sentry.css ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/webapp/css/sentry.css b/sentry-service/sentry-service-server/src/main/webapp/css/sentry.css new file mode 100644 index 0000000..69cba19 --- /dev/null +++ b/sentry-service/sentry-service-server/src/main/webapp/css/sentry.css @@ -0,0 +1,52 @@ +/** + * 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. + */ + +html { + position: relative; + min-height: 100%; +} + +body { + /* Margin bottom by footer height */ + margin-bottom: 60px; + padding-top: 80px; +} + +.navbar-collapse {margin-top:10px} + +.footer { + position: absolute; + bottom: 0; + width: 100%; + /* Set the fixed height of the footer here */ + height: 60px; + background-color: #f5f5f5; +} + +.container .text-muted { + margin: 20px 0; +} + +.footer > .container { + padding-right: 15px; + padding-left: 15px; +} + +code { + font-size: 80%; +}
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/main/webapp/sentry.png ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/webapp/sentry.png b/sentry-service/sentry-service-server/src/main/webapp/sentry.png new file mode 100644 index 0000000..67edd90 Binary files /dev/null and b/sentry-service/sentry-service-server/src/main/webapp/sentry.png differ http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/SentryGenericServiceIntegrationBase.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/SentryGenericServiceIntegrationBase.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/SentryGenericServiceIntegrationBase.java new file mode 100644 index 0000000..a26f4f7 --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/SentryGenericServiceIntegrationBase.java @@ -0,0 +1,73 @@ +/** + * 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.generic.thrift; + +import java.security.PrivilegedExceptionAction; +import java.util.Set; + +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.After; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SentryGenericServiceIntegrationBase extends SentryServiceIntegrationBase { + private static final Logger LOGGER = LoggerFactory.getLogger(SentryGenericServiceIntegrationBase.class); + protected static final String SOLR = "SOLR"; + protected SentryGenericServiceClient client; + + /** + * use the generic client to connect sentry service + */ + @Override + public void connectToSentryService() throws Exception { + // The client should already be logged in when running in solr + // therefore we must manually login in the integration tests + if (kerberos) { + this.client = clientUgi.doAs( new PrivilegedExceptionAction<SentryGenericServiceClient>() { + @Override + public SentryGenericServiceClient run() throws Exception { + return SentryGenericServiceClientFactory.create(conf); + } + }); + } else { + this.client = SentryGenericServiceClientFactory.create(conf); + } + } + + @After + public void after() { + try { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + Set<TSentryRole> tRoles = client.listAllRoles(ADMIN_USER, SOLR); + for (TSentryRole tRole : tRoles) { + client.dropRole(ADMIN_USER, tRole.getRoleName(), SOLR); + } + if(client != null) { + client.close(); + } + } + }); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } finally { + policyFilePath.delete(); + } + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestAuditLogForSentryGenericService.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestAuditLogForSentryGenericService.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestAuditLogForSentryGenericService.java new file mode 100644 index 0000000..e4f67c4 --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestAuditLogForSentryGenericService.java @@ -0,0 +1,296 @@ +/** + * 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.generic.thrift; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.security.PrivilegedExceptionAction; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.sentry.provider.db.log.appender.AuditLoggerTestAppender; +import org.apache.sentry.provider.db.log.util.CommandUtil; +import org.apache.sentry.provider.db.log.util.Constants; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.codehaus.jettison.json.JSONObject; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class TestAuditLogForSentryGenericService extends SentryServiceIntegrationBase { + + private SentryGenericServiceClient client; + private static final String COMPONENT = "SQOOP"; + private static final org.slf4j.Logger LOGGER = LoggerFactory + .getLogger(TestAuditLogForSentryGenericService.class); + + @BeforeClass + public static void setup() throws Exception { + SentryServiceIntegrationBase.setup(); + Logger logger = Logger.getLogger("sentry.generic.authorization.ddl.logger"); + AuditLoggerTestAppender testAppender = new AuditLoggerTestAppender(); + logger.addAppender(testAppender); + logger.setLevel(Level.INFO); + } + + @Override + @After + public void after() { + try { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + Set<TSentryRole> tRoles = client.listAllRoles(SentryServiceIntegrationBase.ADMIN_USER, COMPONENT); + for (TSentryRole tRole : tRoles) { + client.dropRole(SentryServiceIntegrationBase.ADMIN_USER, tRole.getRoleName(), COMPONENT); + } + if (client != null) { + client.close(); + } + } + }); + } catch (Exception e) { + // log the exception + LOGGER.warn("Exception happened after test case.", e); + } finally { + policyFilePath.delete(); + } + } + + /** + * use the generic client to connect sentry service + */ + @Override + public void connectToSentryService() throws Exception { + if (SentryServiceIntegrationBase.kerberos) { + this.client = SentryServiceIntegrationBase.clientUgi.doAs(new PrivilegedExceptionAction<SentryGenericServiceClient>() { + @Override + public SentryGenericServiceClient run() throws Exception { + return SentryGenericServiceClientFactory.create(SentryServiceIntegrationBase.conf); + } + }); + } else { + this.client = SentryGenericServiceClientFactory.create(SentryServiceIntegrationBase.conf); + } + } + + @Test + public void testAuditLogForGenericModel() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = SentryServiceIntegrationBase.ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(SentryServiceIntegrationBase.ADMIN_GROUP); + String roleName = "admin_r"; + String testGroupName = "g1"; + String action = "all"; + String service = "sentryService"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + // test the audit log for create role, success + client.createRole(requestorUserName, roleName, COMPONENT); + Map<String, String> fieldValueMap = new HashMap<String, String>(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // test the audit log for create role, failed + try { + client.createRole(requestorUserName, roleName, COMPONENT); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + // test the audit log for add role to group, success + client.grantRoleToGroups(requestorUserName, roleName, COMPONENT, + Sets.newHashSet(testGroupName)); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE " + roleName + + " TO GROUP " + testGroupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // test the audit log for add role to group, failed + try { + client.grantRoleToGroups(requestorUserName, "invalidRole", COMPONENT, + Sets.newHashSet(testGroupName)); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE invalidRole TO GROUP " + + testGroupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + // test the audit log for grant privilege, success + TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT, service, Lists.newArrayList( + new TAuthorizable("resourceType1", "resourceName1"), new TAuthorizable("resourceType2", + "resourceName2")), action); + client.grantPrivilege(requestorUserName, roleName, COMPONENT, privilege); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, + "GRANT ALL ON resourceType1 resourceName1 resourceType2 resourceName2 TO ROLE " + + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // for error audit log + TSentryPrivilege invalidPrivilege = new TSentryPrivilege(COMPONENT, service, + Lists.newArrayList(new TAuthorizable("resourceType1", "resourceName1")), + "invalidAction"); + // test the audit log for grant privilege, failed + try { + client.grantPrivilege(requestorUserName, roleName, COMPONENT, invalidPrivilege); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, + "GRANT INVALIDACTION ON resourceType1 resourceName1 TO ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + // test the audit log for revoke privilege, success + client.revokePrivilege(requestorUserName, roleName, COMPONENT, privilege); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, + "REVOKE ALL ON resourceType1 resourceName1 resourceType2 resourceName2 FROM ROLE " + + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // test the audit log for revoke privilege, failed + try { + client.revokePrivilege(requestorUserName, "invalidRole", COMPONENT, invalidPrivilege); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, + "REVOKE INVALIDACTION ON resourceType1 resourceName1 FROM ROLE invalidRole"); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + // test the audit log for delete role from group, success + client.revokeRoleFromGroups(requestorUserName, roleName, COMPONENT, + Sets.newHashSet(testGroupName)); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE " + roleName + + " FROM GROUP " + testGroupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + // test the audit log for delete role from group, failed + try { + client.revokeRoleFromGroups(requestorUserName, "invalidRole", COMPONENT, + Sets.newHashSet(testGroupName)); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, + "REVOKE ROLE invalidRole FROM GROUP " + testGroupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + // test the audit log for drop role, success + client.dropRole(requestorUserName, roleName, COMPONENT); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + // test the audit log for drop role, failed + try { + client.dropRole(requestorUserName, roleName, COMPONENT); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_COMPONENT, COMPONENT); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + } + }); + } + + private void assertAuditLog(Map<String, String> fieldValueMap) throws Exception { + assertThat(AuditLoggerTestAppender.getLastLogLevel(), is(Level.INFO)); + JSONObject jsonObject = new JSONObject(AuditLoggerTestAppender.getLastLogEvent()); + if (fieldValueMap != null) { + for (Map.Entry<String, String> entry : fieldValueMap.entrySet()) { + String entryKey = entry.getKey(); + if (Constants.LOG_FIELD_IP_ADDRESS.equals(entryKey)) { + assertTrue(CommandUtil.assertIPInAuditLog(jsonObject.get(entryKey).toString())); + } else { + assertTrue(entry.getValue().equalsIgnoreCase(jsonObject.get(entryKey).toString())); + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericPolicyProcessor.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericPolicyProcessor.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericPolicyProcessor.java new file mode 100644 index 0000000..4c207e9 --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericPolicyProcessor.java @@ -0,0 +1,364 @@ +/** + * 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.generic.thrift; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Matchers.anySetOf; +import static org.mockito.Matchers.anyString; + +import java.util.*; + +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.core.common.Authorizable; +import org.apache.sentry.core.common.exception.SentrySiteConfigurationException; +import org.apache.sentry.core.model.solr.Collection; +import org.apache.sentry.core.model.solr.Field; +import org.apache.sentry.core.model.solr.SolrConstants; +import org.apache.sentry.core.common.exception.SentryAlreadyExistsException; +import org.apache.sentry.core.common.exception.SentryGrantDeniedException; +import org.apache.sentry.core.common.exception.SentryInvalidInputException; +import org.apache.sentry.core.common.exception.SentryNoSuchObjectException; +import org.apache.sentry.provider.common.GroupMappingService; +import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject; +import org.apache.sentry.provider.db.generic.service.persistent.SentryStoreLayer; +import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder; +import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege; +import org.apache.sentry.provider.db.service.model.MSentryRole; +import org.apache.sentry.core.common.utils.PolicyStoreConstants; +import org.apache.sentry.service.common.ServiceConstants.ServerConfig; +import org.apache.sentry.api.common.Status; +import org.apache.sentry.service.thrift.TSentryResponseStatus; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import com.google.common.collect.Sets; + +public class TestSentryGenericPolicyProcessor extends org.junit.Assert { + private static final String ADMIN_GROUP = "admin_group"; + private static final String ADMIN_USER = "admin_user"; + private static final String NOT_ADMIN_USER = "not_admin_user"; + private static final String NOT_ADMIN_GROUP = "not_admin_group"; + private static final String NO_GROUP_USER = "no_group_user"; + + private SentryStoreLayer mockStore = Mockito.mock(SentryStoreLayer.class); + private SentryGenericPolicyProcessor processor; + + @Before + public void setup() throws Exception { + Configuration conf = new Configuration(); + conf.set(ServerConfig.ADMIN_GROUPS, ADMIN_GROUP); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING, MockGroupMapping.class.getName()); + processor = new SentryGenericPolicyProcessor(conf, mockStore); + } + + @Test + public void testNotAdminOperation() throws Exception { + String requestUser = NOT_ADMIN_USER; + Status validateStatus = Status.ACCESS_DENIED; + testOperation(requestUser, validateStatus); + } + + private void testOperation(String requestUser, Status validateStatus) throws Exception { + TCreateSentryRoleRequest createrequest = new TCreateSentryRoleRequest(); + createrequest.setRequestorUserName(requestUser); + createrequest.setRoleName("r1"); + assertEquals(validateStatus, fromTSentryStatus(processor.create_sentry_role(createrequest).getStatus())); + + TDropSentryRoleRequest dropRequest = new TDropSentryRoleRequest(); + dropRequest.setRequestorUserName(requestUser); + dropRequest.setRoleName("r1"); + assertEquals(validateStatus, fromTSentryStatus(processor.drop_sentry_role(dropRequest).getStatus())); + + TAlterSentryRoleAddGroupsRequest addRequest = new TAlterSentryRoleAddGroupsRequest(); + addRequest.setRequestorUserName(requestUser); + addRequest.setRoleName("r1"); + addRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(validateStatus, fromTSentryStatus(processor.alter_sentry_role_add_groups(addRequest).getStatus())); + + TAlterSentryRoleDeleteGroupsRequest delRequest = new TAlterSentryRoleDeleteGroupsRequest(); + delRequest.setRequestorUserName(requestUser); + delRequest.setRoleName("r1"); + delRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(validateStatus, fromTSentryStatus(processor.alter_sentry_role_delete_groups(delRequest).getStatus())); + + TDropPrivilegesRequest dropPrivRequest = new TDropPrivilegesRequest(); + dropPrivRequest.setRequestorUserName(requestUser); + dropPrivRequest.setPrivilege(new TSentryPrivilege("test", "test", new ArrayList<TAuthorizable>(), "test")); + assertEquals(validateStatus, fromTSentryStatus(processor.drop_sentry_privilege(dropPrivRequest).getStatus())); + + TRenamePrivilegesRequest renameRequest = new TRenamePrivilegesRequest(); + renameRequest.setRequestorUserName(requestUser); + assertEquals(validateStatus, fromTSentryStatus(processor.rename_sentry_privilege(renameRequest).getStatus())); + } + + private Status fromTSentryStatus(TSentryResponseStatus status) { + return Status.fromCode(status.getValue()); + } + + @Test + public void testAdminOperation() throws Exception { + testOperation(ADMIN_USER, Status.OK); + } + + @Test + public void testGrantAndRevokePrivilege() throws Exception { + setup(); + + TSentryPrivilege tprivilege = new TSentryPrivilege("test", "test", new ArrayList<TAuthorizable>(), "test"); + tprivilege.setGrantOption(TSentryGrantOption.UNSET); + + TAlterSentryRoleGrantPrivilegeRequest grantRequest = new TAlterSentryRoleGrantPrivilegeRequest(); + grantRequest.setRequestorUserName(ADMIN_USER); + grantRequest.setRoleName("r1"); + grantRequest.setPrivilege(tprivilege); + assertEquals(Status.OK, fromTSentryStatus(processor.alter_sentry_role_grant_privilege(grantRequest).getStatus())); + + TAlterSentryRoleRevokePrivilegeRequest revokeRequest = new TAlterSentryRoleRevokePrivilegeRequest(); + revokeRequest.setRequestorUserName(ADMIN_USER); + revokeRequest.setRoleName("r1"); + revokeRequest.setPrivilege(tprivilege); + assertEquals(Status.OK, fromTSentryStatus(processor.alter_sentry_role_revoke_privilege(revokeRequest).getStatus())); + } + + @Test + public void testOperationWithException() throws Exception { + String roleName = anyString(); + Mockito.when(mockStore.createRole(anyString(), roleName, anyString())) + .thenThrow(new SentryAlreadyExistsException("Role: " + roleName)); + + roleName = anyString(); + Mockito.when(mockStore.dropRole(anyString(), roleName, anyString())) + .thenThrow(new SentryNoSuchObjectException("Role: " + roleName )); + + roleName = anyString(); + Mockito.when(mockStore.alterRoleAddGroups(anyString(), roleName, anySetOf(String.class),anyString())) + .thenThrow(new SentryNoSuchObjectException("Role: " + roleName)); + + roleName = anyString(); + Mockito.when(mockStore.alterRoleDeleteGroups(anyString(), roleName, anySetOf(String.class), anyString())) + .thenThrow(new SentryNoSuchObjectException("Role: " + roleName)); + + roleName = anyString(); + Mockito.when(mockStore.alterRoleGrantPrivilege(anyString(), roleName, any(PrivilegeObject.class), anyString())) + .thenThrow(new SentryGrantDeniedException("Role: " + roleName + " is not allowed to do grant")); + + roleName = anyString(); + Mockito.when(mockStore.alterRoleRevokePrivilege(anyString(), roleName, any(PrivilegeObject.class), anyString())) + .thenThrow(new SentryGrantDeniedException("Role: " + roleName + " is not allowed to do grant")); + + Mockito.when(mockStore.dropPrivilege(anyString(), any(PrivilegeObject.class), anyString())) + .thenThrow(new SentryInvalidInputException("Invalid input privilege object")); + + Mockito.when(mockStore.renamePrivilege(anyString(), anyString(), anyListOf(Authorizable.class), + anyListOf(Authorizable.class), anyString())) + .thenThrow(new RuntimeException("Unknown error")); + + setup(); + + TCreateSentryRoleRequest createrequest = new TCreateSentryRoleRequest(); + createrequest.setRequestorUserName(ADMIN_USER); + createrequest.setRoleName("r1"); + assertEquals(Status.ALREADY_EXISTS, fromTSentryStatus(processor.create_sentry_role(createrequest).getStatus())); + + TDropSentryRoleRequest dropRequest = new TDropSentryRoleRequest(); + dropRequest.setRequestorUserName(ADMIN_USER); + dropRequest.setRoleName("r1"); + assertEquals(Status.NO_SUCH_OBJECT, fromTSentryStatus(processor.drop_sentry_role(dropRequest).getStatus())); + + TAlterSentryRoleAddGroupsRequest addRequest = new TAlterSentryRoleAddGroupsRequest(); + addRequest.setRequestorUserName(ADMIN_USER); + addRequest.setRoleName("r1"); + addRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(Status.NO_SUCH_OBJECT, fromTSentryStatus(processor.alter_sentry_role_add_groups(addRequest).getStatus())); + + TAlterSentryRoleDeleteGroupsRequest delRequest = new TAlterSentryRoleDeleteGroupsRequest(); + delRequest.setRequestorUserName(ADMIN_USER); + delRequest.setRoleName("r1"); + delRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(Status.NO_SUCH_OBJECT, fromTSentryStatus(processor.alter_sentry_role_delete_groups(delRequest).getStatus())); + + TDropPrivilegesRequest dropPrivRequest = new TDropPrivilegesRequest(); + dropPrivRequest.setRequestorUserName(ADMIN_USER); + dropPrivRequest.setPrivilege(new TSentryPrivilege("test", "test", new ArrayList<TAuthorizable>(), "test")); + assertEquals(Status.INVALID_INPUT, fromTSentryStatus(processor.drop_sentry_privilege(dropPrivRequest).getStatus())); + + TRenamePrivilegesRequest renameRequest = new TRenamePrivilegesRequest(); + renameRequest.setRequestorUserName(ADMIN_USER); + assertEquals(Status.RUNTIME_ERROR, fromTSentryStatus(processor.rename_sentry_privilege(renameRequest).getStatus())); + + TSentryPrivilege tprivilege = new TSentryPrivilege("test", "test", new ArrayList<TAuthorizable>(), "test"); + tprivilege.setGrantOption(TSentryGrantOption.UNSET); + + TAlterSentryRoleGrantPrivilegeRequest grantRequest = new TAlterSentryRoleGrantPrivilegeRequest(); + grantRequest.setRequestorUserName(ADMIN_USER); + grantRequest.setRoleName("r1"); + grantRequest.setPrivilege(tprivilege); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.alter_sentry_role_grant_privilege(grantRequest).getStatus())); + + TAlterSentryRoleRevokePrivilegeRequest revokeRequest = new TAlterSentryRoleRevokePrivilegeRequest(); + revokeRequest.setRequestorUserName(ADMIN_USER); + revokeRequest.setRoleName("r1"); + revokeRequest.setPrivilege(tprivilege); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.alter_sentry_role_revoke_privilege(revokeRequest).getStatus())); + } + + @Test + public void testUserWithNoGroup() throws Exception { + setup(); + + TCreateSentryRoleRequest createrequest = new TCreateSentryRoleRequest(); + createrequest.setRequestorUserName(NO_GROUP_USER); + createrequest.setRoleName("r1"); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.create_sentry_role(createrequest).getStatus())); + + TDropSentryRoleRequest dropRequest = new TDropSentryRoleRequest(); + dropRequest.setRequestorUserName(NO_GROUP_USER); + dropRequest.setRoleName("r1"); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.drop_sentry_role(dropRequest).getStatus())); + + TAlterSentryRoleAddGroupsRequest addRequest = new TAlterSentryRoleAddGroupsRequest(); + addRequest.setRequestorUserName(NO_GROUP_USER); + addRequest.setRoleName("r1"); + addRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.alter_sentry_role_add_groups(addRequest).getStatus())); + + TAlterSentryRoleDeleteGroupsRequest delRequest = new TAlterSentryRoleDeleteGroupsRequest(); + delRequest.setRequestorUserName(NO_GROUP_USER); + delRequest.setRoleName("r1"); + delRequest.setGroups(Sets.newHashSet("g1")); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.alter_sentry_role_delete_groups(delRequest).getStatus())); + + TDropPrivilegesRequest dropPrivRequest = new TDropPrivilegesRequest(); + dropPrivRequest.setRequestorUserName(NO_GROUP_USER); + dropPrivRequest.setPrivilege(new TSentryPrivilege("test", "test", new ArrayList<TAuthorizable>(), "test")); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.drop_sentry_privilege(dropPrivRequest).getStatus())); + + TRenamePrivilegesRequest renameRequest = new TRenamePrivilegesRequest(); + renameRequest.setRequestorUserName(NO_GROUP_USER); + assertEquals(Status.ACCESS_DENIED, fromTSentryStatus(processor.rename_sentry_privilege(renameRequest).getStatus())); + + // Can't test GrantPrivilege / RevokePrivilege since the authorization happens + // in the persistence layer, which isn't setup in this test. + } + + @Test + public void testGetRolesAndPrivileges() throws Exception { + String roleName = "r1"; + String groupName = "g1"; + PrivilegeObject queryPrivilege = new Builder() + .setComponent("SOLR") + .setAction(SolrConstants.QUERY) + .setService("service1") + .setAuthorizables(Arrays.asList(new Collection("c1"), new Field("f1"))) + .build(); + PrivilegeObject updatePrivilege = new Builder(queryPrivilege) + .setAction(SolrConstants.UPDATE) + .build(); + + MSentryGMPrivilege mSentryGMPrivilege = new MSentryGMPrivilege("SOLR", "service1", + Arrays.asList(new Collection("c1"), new Field("f1")), + SolrConstants.QUERY, true); + + MSentryRole role = new MSentryRole("r1", 290); + mSentryGMPrivilege.setRoles(Sets.newHashSet(role)); + + Mockito.when(mockStore.getRolesByGroups(anyString(), anySetOf(String.class))) + .thenReturn(Sets.newHashSet(roleName)); + + Mockito.when(mockStore.getPrivilegesByProvider(anyString(), anyString(), anySetOf(String.class), + anySetOf(String.class), anyListOf(Authorizable.class))) + .thenReturn(Sets.newHashSet(queryPrivilege, updatePrivilege)); + + Mockito.when(mockStore.getGroupsByRoles(anyString(), anySetOf(String.class))) + .thenReturn(Sets.newHashSet(groupName)); + + Mockito.when(mockStore.getPrivilegesByAuthorizable(anyString(), anyString(), anySetOf(String.class), anyListOf(Authorizable.class))) + .thenReturn(Sets.newHashSet(mSentryGMPrivilege)); + + Mockito.when(mockStore.getAllRoleNames()) + .thenReturn(Sets.newHashSet(roleName)); + + TListSentryPrivilegesRequest request1 = new TListSentryPrivilegesRequest(); + request1.setRoleName(roleName); + request1.setRequestorUserName(ADMIN_USER); + TListSentryPrivilegesResponse response1 = processor.list_sentry_privileges_by_role(request1); + assertEquals(Status.OK, fromTSentryStatus(response1.getStatus())); + assertEquals(2, response1.getPrivileges().size()); + + TListSentryRolesRequest request2 = new TListSentryRolesRequest(); + request2.setRequestorUserName(ADMIN_USER); + request2.setGroupName(groupName); + TListSentryRolesResponse response2 = processor.list_sentry_roles_by_group(request2); + assertEquals(Status.OK, fromTSentryStatus(response2.getStatus())); + assertEquals(1, response2.getRoles().size()); + + TListSentryPrivilegesForProviderRequest request3 = new TListSentryPrivilegesForProviderRequest(); + request3.setGroups(Sets.newHashSet(groupName)); + request3.setRoleSet(new TSentryActiveRoleSet(true, null)); + TListSentryPrivilegesForProviderResponse response3 = processor.list_sentry_privileges_for_provider(request3); + assertEquals(Status.OK, fromTSentryStatus(response3.getStatus())); + assertEquals(2, response3.getPrivileges().size()); + + // Optional parameters activeRoleSet and requested group name are both provided. + TListSentryPrivilegesByAuthRequest request4 = new TListSentryPrivilegesByAuthRequest(); + request4.setGroups(Sets.newHashSet(groupName)); + request4.setRoleSet(new TSentryActiveRoleSet(true, null)); + request4.setRequestorUserName(ADMIN_USER); + Set<String> authorizablesSet = Sets.newHashSet("Collection=c1->Field=f1"); + request4.setAuthorizablesSet(authorizablesSet); + + TListSentryPrivilegesByAuthResponse response4 = processor.list_sentry_privileges_by_authorizable(request4); + assertEquals(Status.OK, fromTSentryStatus(response4.getStatus())); + assertEquals(1, response4.getPrivilegesMapByAuth().size()); + + // Optional parameters activeRoleSet and requested group name are both not provided. + TListSentryPrivilegesByAuthRequest request5 = new TListSentryPrivilegesByAuthRequest(); + request5.setRequestorUserName("not_" + ADMIN_USER); + authorizablesSet = Sets.newHashSet("Collection=c1->Field=f2"); + request5.setAuthorizablesSet(authorizablesSet); + + TListSentryPrivilegesByAuthResponse response5 = processor.list_sentry_privileges_by_authorizable(request5); + assertEquals(Status.OK, fromTSentryStatus(response5.getStatus())); + assertEquals(1, response5.getPrivilegesMapByAuth().size()); + } + + @Test(expected=SentrySiteConfigurationException.class) + public void testConfigCannotCreateNotificationHandler() throws Exception { + Configuration conf = new Configuration(); + conf.set(PolicyStoreConstants.SENTRY_GENERIC_POLICY_NOTIFICATION,"junk"); + SentryGenericPolicyProcessor.createHandlers(conf); + } + + public static class MockGroupMapping implements GroupMappingService { + public MockGroupMapping(Configuration conf, String resource) { //NOPMD + } + @Override + public Set<String> getGroups(String user) { + if (user.equalsIgnoreCase(ADMIN_USER)) { + return Sets.newHashSet(ADMIN_GROUP); + } else if (user.equalsIgnoreCase(NOT_ADMIN_USER)){ + return Sets.newHashSet(NOT_ADMIN_GROUP); + } else { + return Collections.emptySet(); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceClient.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceClient.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceClient.java new file mode 100644 index 0000000..9ef5f7f --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceClient.java @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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.generic.thrift; + +import java.util.Set; + +import org.apache.sentry.service.thrift.SentryServiceFactory; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.Sets; + +public class TestSentryGenericServiceClient extends SentryGenericServiceIntegrationBase { + + @BeforeClass + public static void setup() throws Exception { + SentryServiceIntegrationBase.beforeSetup(); + SentryServiceIntegrationBase.setupConf(); + SentryServiceIntegrationBase.startSentryService(); + SentryServiceIntegrationBase.afterSetup(); + SentryServiceIntegrationBase.kerberos = false; + } + + @Test + public void testConnectionWhenReconnect() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = SentryServiceIntegrationBase.ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(SentryServiceIntegrationBase.ADMIN_GROUP); + String roleName = "admin_r"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName, "solr"); + client.createRole(requestorUserName, roleName, "solr"); + stopSentryService(); + SentryServiceIntegrationBase.server = SentryServiceFactory.create(SentryServiceIntegrationBase.conf); + SentryServiceIntegrationBase.startSentryService(); + client.dropRole(requestorUserName, roleName, "solr"); + } + }); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceIntegration.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceIntegration.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceIntegration.java new file mode 100644 index 0000000..8a3ce02 --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/generic/thrift/TestSentryGenericServiceIntegration.java @@ -0,0 +1,503 @@ +/** + * 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.generic.thrift; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.sentry.core.common.exception.SentryUserException; +import org.apache.sentry.core.common.ActiveRoleSet; +import org.apache.sentry.core.common.Authorizable; +import org.apache.sentry.core.model.solr.Collection; +import org.apache.sentry.core.model.solr.Field; +import org.apache.sentry.core.model.solr.SolrConstants; +import org.junit.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class TestSentryGenericServiceIntegration extends SentryGenericServiceIntegrationBase { + + @Test + public void testCreateDropShowRole() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_r"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName, SOLR); + + client.createRole(requestorUserName, roleName, SOLR); + + client.grantRoleToGroups(requestorUserName, roleName, SOLR, Sets.newHashSet(requestorUserGroupNames)); + + Set<TSentryRole> roles = client.listUserRoles(requestorUserName,SOLR); + assertEquals("Incorrect number of roles", 1, roles.size()); + for (TSentryRole role:roles) { + assertTrue(role.getRoleName(), role.getRoleName().equalsIgnoreCase(roleName)); + } + client.dropRole(requestorUserName, roleName, SOLR); + }}); + } + + @Test + public void testAddDeleteRoleToGroup() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String testGroupName = "g1"; + String roleName = "admin_r"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + setLocalGroupMapping(requestorUserName, Sets.newHashSet(testGroupName)); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName, SOLR); + + client.createRole(requestorUserName, roleName, SOLR); + + client.grantRoleToGroups(requestorUserName, roleName, SOLR, Sets.newHashSet(testGroupName)); + + Set<TSentryRole> roles = client.listUserRoles(requestorUserName,SOLR); + assertEquals("Incorrect number of roles", 1, roles.size()); + for (TSentryRole role:roles) { + assertTrue(role.getRoleName(), role.getRoleName().equalsIgnoreCase(roleName)); + assertTrue(role.getGroups().size() == 1); + for (String group :role.getGroups()) { + assertEquals(testGroupName, group); + } + } + + client.revokeRoleFromGroups(requestorUserName, roleName, SOLR, Sets.newHashSet(testGroupName)); + roles = client.listUserRoles(requestorUserName,SOLR); + assertEquals("Incorrect number of roles", 0, roles.size()); + + client.dropRole(requestorUserName, roleName, SOLR); + }}); + } + + @Test + public void testGranRevokePrivilege() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName1 = "admin_r1"; + String roleName2 = "admin_r2"; + + client.dropRoleIfExists(requestorUserName, roleName1, SOLR); + client.createRole(requestorUserName, roleName1, SOLR); + + client.dropRoleIfExists(requestorUserName, roleName2, SOLR); + client.createRole(requestorUserName, roleName2, SOLR); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + TSentryPrivilege updatePrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.UPDATE); + + client.grantPrivilege(requestorUserName, roleName1, SOLR, queryPrivilege); + client.grantPrivilege(requestorUserName, roleName2, SOLR, updatePrivilege); + + client.revokePrivilege(requestorUserName, roleName1, SOLR, queryPrivilege); + client.revokePrivilege(requestorUserName, roleName2, SOLR, updatePrivilege); + }}); + } + + @Test + public void testMultipleRolesSamePrivilege() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName1 = "admin_r1"; + String roleName2 = "admin_r2"; + + client.dropRoleIfExists(requestorUserName, roleName1, SOLR); + client.createRole(requestorUserName, roleName1, SOLR); + + client.dropRoleIfExists(requestorUserName, roleName2, SOLR); + client.createRole(requestorUserName, roleName2, SOLR); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + client.grantPrivilege(requestorUserName, roleName1, SOLR, queryPrivilege); + Set<TSentryPrivilege> listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1, SOLR, "service1"); + assertTrue("Privilege not assigned to role1 !!", listPrivilegesByRoleName.size() == 1); + + client.grantPrivilege(requestorUserName, roleName2, SOLR, queryPrivilege); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2, SOLR, "service1"); + 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<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_r1"; + String groupName = "group1"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + setLocalGroupMapping(requestorUserName, Sets.newHashSet(groupName)); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName, SOLR); + client.createRole(requestorUserName, roleName, SOLR); + client.grantRoleToGroups(requestorUserName, roleName, SOLR, Sets.newHashSet(groupName)); + + Set<TSentryRole> groupRoles = client.listRolesByGroupName(requestorUserName, groupName,SOLR); + assertTrue(groupRoles.size() == 1); + for (TSentryRole role:groupRoles) { + assertTrue(role.getRoleName(), role.getRoleName().equalsIgnoreCase(roleName)); + assertTrue(role.getGroups().size() == 1); + for (String group :role.getGroups()) { + assertEquals(groupName, group); + } + } + + client.dropRole(requestorUserName, roleName, SOLR); + }}); + } + + @Test + public void testShowGrant() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_r1"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName, SOLR); + client.createRole(requestorUserName, roleName, SOLR); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + TSentryPrivilege updatePrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.UPDATE); + + client.grantPrivilege(requestorUserName, roleName, SOLR, updatePrivilege); + client.grantPrivilege(requestorUserName, roleName, SOLR, queryPrivilege); + Set<TSentryPrivilege> privileges = client.listAllPrivilegesByRoleName(requestorUserName, roleName, SOLR, "service1"); + assertTrue(privileges.size() == 2); + + client.revokePrivilege(requestorUserName, roleName, SOLR, updatePrivilege); + privileges = client.listAllPrivilegesByRoleName(requestorUserName, roleName, SOLR, "service1"); + assertTrue(privileges.size() == 1); + }}); + } + + @Test + public void testSameGrantTwice() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName = "admin_r1"; + + client.createRole(requestorUserName, roleName, SOLR); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + client.grantPrivilege(requestorUserName, roleName, SOLR, queryPrivilege); + assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName, SOLR, "service1").size()); + }}); + } + + @Test + public void testGrantRevokeWithGrantOption() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String adminUser = ADMIN_USER; + Set<String> adminGroup = Sets.newHashSet(ADMIN_GROUP); + String grantOptionUser = "user1"; + Set<String> grantOptionGroup = Sets.newHashSet("group1"); + String noGrantOptionUser = "user2"; + Set<String> noGrantOptionGroup = Sets.newHashSet("group2"); + + setLocalGroupMapping(adminUser, adminGroup); + setLocalGroupMapping(grantOptionUser, grantOptionGroup); + setLocalGroupMapping(noGrantOptionUser, noGrantOptionGroup); + writePolicyFile(); + + String grantRole = "grant_r"; + String noGrantRole = "no_grant_r"; + String testRole = "test_role"; + + client.createRole(adminUser, grantRole, SOLR); + client.createRole(adminUser, noGrantRole, SOLR); + client.createRole(adminUser, testRole, SOLR); + + TSentryPrivilege grantPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"))), + SolrConstants.QUERY); + grantPrivilege.setGrantOption(TSentryGrantOption.TRUE); + + TSentryPrivilege noGrantPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"))), + SolrConstants.QUERY); + noGrantPrivilege.setGrantOption(TSentryGrantOption.FALSE); + + TSentryPrivilege testPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + testPrivilege.setGrantOption(TSentryGrantOption.FALSE); + + client.grantPrivilege(adminUser, grantRole, SOLR, grantPrivilege); + client.grantPrivilege(adminUser, noGrantRole, SOLR, noGrantPrivilege); + + client.grantRoleToGroups(adminUser, grantRole, SOLR, grantOptionGroup); + client.grantRoleToGroups(adminUser, noGrantRole, SOLR, noGrantOptionGroup); + + try { + client.grantPrivilege(grantOptionUser,testRole,SOLR, testPrivilege); + } catch (SentryUserException e) { + fail("grantOptionUser failed grant privilege to user"); + } + + try { + client.grantPrivilege(noGrantOptionUser, testRole, SOLR, testPrivilege); + fail("noGrantOptionUser can't grant privilege to user"); + } catch (SentryUserException e) { + } + + try { + client.revokePrivilege(grantOptionUser, testRole, SOLR, testPrivilege); + } catch(SentryUserException e) { + fail("grantOptionUser failed revoke privilege to user"); + } + + try { + client.revokePrivilege(noGrantOptionUser, testRole, SOLR, testPrivilege); + fail("noGrantOptionUser can't revoke privilege to user"); + } catch (SentryUserException e) { + } + }}); + } + + @Test + public void testGetPrivilegeByHierarchy() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String adminUser = ADMIN_USER; + Set<String> adminGroup = Sets.newHashSet(ADMIN_GROUP); + String testRole = "role1"; + Set<String> testGroup = Sets.newHashSet("group1"); + String testUser = "user1"; + setLocalGroupMapping(adminUser, adminGroup); + setLocalGroupMapping(testUser, testGroup); + writePolicyFile(); + + + client.createRole(adminUser, testRole, SOLR); + client.grantRoleToGroups(adminUser, testRole, SOLR, testGroup); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + TSentryPrivilege updatePrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c2"), new Field("f2"))), + SolrConstants.UPDATE); + + client.grantPrivilege(adminUser, testRole, SOLR, queryPrivilege); + client.grantPrivilege(adminUser, testRole, SOLR, updatePrivilege); + + assertEquals(2, client.listAllPrivilegesByRoleName(testUser, testRole, SOLR, "service1").size()); + + assertEquals(1, client.listPrivilegesByRoleName(testUser, testRole, + SOLR, "service1", Arrays.asList(new Collection("c1"))).size()); + + assertEquals(1, client.listPrivilegesByRoleName(testUser, testRole, + SOLR, "service1", Arrays.asList(new Collection("c2"))).size()); + + assertEquals(1, client.listPrivilegesByRoleName(testUser, testRole, + SOLR, "service1", Arrays.asList(new Collection("c1"), new Field("f1"))).size()); + + assertEquals(1, client.listPrivilegesByRoleName(testUser, testRole, + SOLR, "service1", Arrays.asList(new Collection("c2"), new Field("f2"))).size()); + + //test listPrivilegesForProvider by group(testGroup) + ActiveRoleSet roleSet = ActiveRoleSet.ALL; + + assertEquals(1, client.listPrivilegesForProvider(SOLR, "service1", roleSet, + testGroup, Arrays.asList(new Collection("c1"))).size()); + + assertEquals(1, client.listPrivilegesForProvider(SOLR, "service1", roleSet, + testGroup, Arrays.asList(new Collection("c2"))).size()); + + assertEquals(1, client.listPrivilegesForProvider(SOLR, "service1", roleSet, + testGroup, Arrays.asList(new Collection("c1"), new Field("f1"))).size()); + + assertEquals(1, client.listPrivilegesForProvider(SOLR, "service1", roleSet, + testGroup, Arrays.asList(new Collection("c2"), new Field("f2"))).size()); + }}); + } + + @Test + public void testGetPrivilegeByAuthorizable() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String adminUser = ADMIN_USER; + Set<String> adminGroup = Sets.newHashSet(ADMIN_GROUP); + String testRole = "role1"; + Set<String> testGroup = Sets.newHashSet("group1"); + String testUser = "user1"; + setLocalGroupMapping(adminUser, adminGroup); + setLocalGroupMapping(testUser, testGroup); + writePolicyFile(); + + client.createRole(adminUser, testRole, SOLR); + client.grantRoleToGroups(adminUser, testRole, SOLR, adminGroup); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + + TSentryPrivilege updatePrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f2"))), + SolrConstants.UPDATE); + + client.grantPrivilege(adminUser, testRole, SOLR, queryPrivilege); + client.grantPrivilege(adminUser, testRole, SOLR, updatePrivilege); + + //test listPrivilegesbyAuthorizable without requested group and active role set. + assertEquals(1, client.listPrivilegesbyAuthorizable(SOLR, "service1", adminUser, + Sets.newHashSet(new String("Collection=c1->Field=f1")), null, null).size()); + + //test listPrivilegesbyAuthorizable with requested group (testGroup) + Map<String, TSentryPrivilegeMap> privilegeMap = client.listPrivilegesbyAuthorizable(SOLR, + "service1", adminUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), testGroup, null); + TSentryPrivilegeMap actualMap = privilegeMap.get(new String("Collection=c1->Field=f1")); + assertEquals(0, actualMap.getPrivilegeMap().size()); + + //test listPrivilegesbyAuthorizable with active role set. + ActiveRoleSet roleSet = ActiveRoleSet.ALL; + assertEquals(1, client.listPrivilegesbyAuthorizable(SOLR, "service1", adminUser, + Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet).size()); + privilegeMap = client.listPrivilegesbyAuthorizable(SOLR, + "service1", adminUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet); + actualMap = privilegeMap.get(new String("Collection=c1->Field=f1")); + assertEquals(1, actualMap.getPrivilegeMap().size()); + + privilegeMap = client.listPrivilegesbyAuthorizable(SOLR, + "service1", testUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet); + actualMap = privilegeMap.get(new String("Collection=c1->Field=f1")); + assertEquals(0, actualMap.getPrivilegeMap().size()); + + // grant tesRole to testGroup. + client.grantRoleToGroups(adminUser, testRole, SOLR, testGroup); + + privilegeMap = client.listPrivilegesbyAuthorizable(SOLR, + "service1", testUser, Sets.newHashSet(new String("Collection=c1")), null, roleSet); + actualMap = privilegeMap.get(new String("Collection=c1")); + assertEquals(1, actualMap.getPrivilegeMap().size()); + assertEquals(2, actualMap.getPrivilegeMap().get(testRole).size()); + }}); + } + + @Test + public void testDropAndRenamePrivilege() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName = "admin_r1"; + + client.createRole(requestorUserName, roleName, SOLR); + + TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))), + SolrConstants.QUERY); + client.grantPrivilege(requestorUserName, roleName, SOLR, queryPrivilege); + + assertEquals(1, client.listPrivilegesByRoleName(requestorUserName, roleName, + SOLR, "service1", Arrays.asList(new Collection("c1"), new Field("f1"))).size()); + + assertEquals(0, client.listPrivilegesByRoleName(requestorUserName, roleName, + SOLR, "service1", Arrays.asList(new Collection("c2"), new Field("f2"))).size()); + + client.renamePrivilege(requestorUserName, SOLR, "service1", Arrays.asList(new Collection("c1"), new Field("f1")), + Arrays.asList(new Collection("c2"), new Field("f2"))); + + assertEquals(0, client.listPrivilegesByRoleName(requestorUserName, roleName, + SOLR, "service1", Arrays.asList(new Collection("c1"), new Field("f1"))).size()); + + assertEquals(1, client.listPrivilegesByRoleName(requestorUserName, roleName, + SOLR, "service1", Arrays.asList(new Collection("c2"), new Field("f2"))).size()); + + TSentryPrivilege dropPrivilege = new TSentryPrivilege(SOLR, "service1", + fromAuthorizable(Arrays.asList(new Collection("c2"), new Field("f2"))), + SolrConstants.QUERY); + + client.dropPrivilege(requestorUserName, SOLR, dropPrivilege); + + assertEquals(0, client.listPrivilegesByRoleName(requestorUserName, roleName, + SOLR, "service1", Arrays.asList(new Collection("c2"), new Field("f2"))).size()); + }}); + } + + private List<TAuthorizable> fromAuthorizable(List<? extends Authorizable> authorizables) { + List<TAuthorizable> tAuthorizables = Lists.newArrayList(); + for (Authorizable authorizable : authorizables) { + tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName())); + } + return tAuthorizables; + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/SentryMiniKdcTestcase.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/SentryMiniKdcTestcase.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/SentryMiniKdcTestcase.java new file mode 100644 index 0000000..fb5c9a0 --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/SentryMiniKdcTestcase.java @@ -0,0 +1,68 @@ +/** + * 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.io.File; +import java.util.Properties; + +import org.apache.hadoop.minikdc.MiniKdc; + +public class SentryMiniKdcTestcase { + + private static File workDir; + private static Properties conf; + private static MiniKdc kdc; + + public static void startMiniKdc(Properties confOverlay) throws Exception { + createTestDir(); + createMiniKdcConf(confOverlay); + kdc = new MiniKdc(conf, workDir); + kdc.start(); + } + + private static void createMiniKdcConf(Properties confOverlay) { + conf = MiniKdc.createConf(); + for ( Object property : confOverlay.keySet()) { + conf.put(property, confOverlay.get(property)); + } + } + + private static void createTestDir() { + workDir = new File(System.getProperty("test.dir", "target")); + } + + public static void stopMiniKdc() { + if (kdc != null) { + kdc.stop(); + } + } + + public static MiniKdc getKdc() { + return kdc; + } + + public static File getWorkDir() { + return workDir; + } + + public Properties getConf() { + return conf; + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestAuthorizingDDLAuditLogWithKerberos.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestAuthorizingDDLAuditLogWithKerberos.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestAuthorizingDDLAuditLogWithKerberos.java new file mode 100644 index 0000000..92d8eed --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestAuthorizingDDLAuditLogWithKerberos.java @@ -0,0 +1,295 @@ +/** + * 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.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.sentry.provider.db.log.appender.AuditLoggerTestAppender; +import org.apache.sentry.provider.db.log.util.CommandUtil; +import org.apache.sentry.provider.db.log.util.Constants; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.codehaus.jettison.json.JSONObject; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.Sets; + +public class TestAuthorizingDDLAuditLogWithKerberos extends SentryServiceIntegrationBase { + + @BeforeClass + public static void setupLog4j() throws Exception { + Logger logger = Logger.getLogger("sentry.hive.authorization.ddl.logger"); + AuditLoggerTestAppender testAppender = new AuditLoggerTestAppender(); + logger.addAppender(testAppender); + logger.setLevel(Level.INFO); + } + + @Test + public void testBasic() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = SentryServiceIntegrationBase.ADMIN_USER; + Set<String> requestorUserGroupNames = Sets.newHashSet(SentryServiceIntegrationBase.ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + String roleName = "testRole"; + String errorRoleName = "errorRole"; + String serverName = "server1"; + String groupName = "testGroup"; + String dbName = "dbTest"; + String tableName = "tableTest"; + Map<String, String> fieldValueMap = new HashMap<String, String>(); + + // for successful audit log + client.createRole(requestorUserName, roleName); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + // for ip address, there is another logic to test the result + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.grantRoleToGroup(requestorUserName, groupName, roleName); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE " + roleName + + " TO GROUP " + groupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.grantDatabasePrivilege(requestorUserName, roleName, serverName, dbName, "ALL"); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ALL ON DATABASE " + dbName + + " TO ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_DATABASE_NAME, dbName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.grantTablePrivilege(requestorUserName, roleName, serverName, dbName, tableName, + "SELECT", true); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON TABLE " + tableName + + " TO ROLE " + roleName + " WITH GRANT OPTION"); + fieldValueMap.put(Constants.LOG_FIELD_TABLE_NAME, tableName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // for error audit log + try { + client.createRole(requestorUserName, roleName); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_CREATE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "CREATE ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + try { + client.grantRoleToGroup(requestorUserName, groupName, errorRoleName); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_ADD_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE " + errorRoleName + + " TO GROUP " + groupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + try { + client + .grantDatabasePrivilege(requestorUserName, errorRoleName, serverName, dbName, "ALL"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ALL ON DATABASE " + dbName + + " TO ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + try { + client.grantDatabasePrivilege(requestorUserName, errorRoleName, serverName, dbName, + "INSERT"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT INSERT ON DATABASE " + + dbName + " TO ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + try { + client.grantDatabasePrivilege(requestorUserName, errorRoleName, serverName, dbName, + "SELECT"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON DATABASE " + + dbName + " TO ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + try { + client.grantTablePrivilege(requestorUserName, errorRoleName, serverName, dbName, + tableName, "SELECT"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_GRANT_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT SELECT ON TABLE " + + tableName + " TO ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + client.revokeTablePrivilege(requestorUserName, roleName, serverName, dbName, tableName, + "SELECT"); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE SELECT ON TABLE " + tableName + + " FROM ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_TABLE_NAME, tableName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.revokeDatabasePrivilege(requestorUserName, roleName, serverName, dbName, "ALL"); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ALL ON DATABASE " + dbName + + " FROM ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_DATABASE_NAME, dbName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.revokeRoleFromGroup(requestorUserName, groupName, roleName); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE " + roleName + + " FROM GROUP " + groupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + client.dropRole(requestorUserName, roleName); + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE " + roleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + + // for error audit log + try { + client.revokeTablePrivilege(requestorUserName, errorRoleName, serverName, dbName, + tableName, "SELECT"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE SELECT ON TABLE " + + tableName + " FROM ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + try { + client.revokeDatabasePrivilege(requestorUserName, errorRoleName, serverName, dbName, + "ALL"); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_REVOKE_PRIVILEGE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ALL ON DATABASE " + dbName + + " FROM ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + try { + client.revokeRoleFromGroup(requestorUserName, groupName, errorRoleName); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DELETE_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE " + errorRoleName + + " FROM GROUP " + groupName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + + try { + client.dropRole(requestorUserName, errorRoleName); + fail("Exception should have been thrown"); + } catch (Exception e) { + fieldValueMap.clear(); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION, Constants.OPERATION_DROP_ROLE); + fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "DROP ROLE " + errorRoleName); + fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.FALSE); + fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null); + assertAuditLog(fieldValueMap); + } + } + }); + } + + private void assertAuditLog(Map<String, String> fieldValueMap) throws Exception { + assertThat(AuditLoggerTestAppender.getLastLogLevel(), is(Level.INFO)); + JSONObject jsonObject = new JSONObject(AuditLoggerTestAppender.getLastLogEvent()); + if (fieldValueMap != null) { + for (Map.Entry<String, String> entry : fieldValueMap.entrySet()) { + String entryKey = entry.getKey(); + if (Constants.LOG_FIELD_IP_ADDRESS.equals(entryKey)) { + assertTrue(CommandUtil.assertIPInAuditLog(jsonObject.get(entryKey).toString())); + } else { + assertTrue(entry.getValue().equalsIgnoreCase(jsonObject.get(entryKey).toString())); + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestConnectionWithTicketTimeout.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestConnectionWithTicketTimeout.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestConnectionWithTicketTimeout.java new file mode 100644 index 0000000..7d8c58d --- /dev/null +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestConnectionWithTicketTimeout.java @@ -0,0 +1,57 @@ +/** + * 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.hadoop.minikdc.MiniKdc; +import org.apache.sentry.service.common.ServiceConstants; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore("SENTRY-515: Not part of automated unit testing, as it takes too long. Fails until we move to a hadoop 2.6.1. See HADOOP-10786") +public class TestConnectionWithTicketTimeout extends + org.apache.sentry.service.thrift.SentryServiceIntegrationBase { + + @BeforeClass + public static void setup() throws Exception { + kerberos = true; + beforeSetup(); + setupConf(); + startSentryService(); + afterSetup(); + } + + public static void beforeSetup() throws Exception { + kdcConfOverlay.setProperty(MiniKdc.MAX_TICKET_LIFETIME, "360001"); + //Only UGI based client connections renew their TGT, this is not a problem in the real world + // as this is not configurable and always true + conf.set(ServiceConstants.ServerConfig.SECURITY_USE_UGI_TRANSPORT, "true"); + } + + /*** + * Test is run only when sentry.hive.test.ticket.timeout is set to "true" + * @throws Exception + */ + @Test + public void testConnectionAfterTicketTimeout() throws Exception { + Thread.sleep(400000); + connectToSentryService(); + } + +}
