001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.access; 019 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertTrue; 022 023import java.util.ArrayList; 024import java.util.List; 025import java.util.concurrent.atomic.AtomicBoolean; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.Abortable; 028import org.apache.hadoop.hbase.HBaseClassTestRule; 029import org.apache.hadoop.hbase.HBaseTestingUtility; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.Waiter.Predicate; 032import org.apache.hadoop.hbase.security.User; 033import org.apache.hadoop.hbase.testclassification.LargeTests; 034import org.apache.hadoop.hbase.testclassification.SecurityTests; 035import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 036import org.junit.AfterClass; 037import org.junit.BeforeClass; 038import org.junit.ClassRule; 039import org.junit.Test; 040import org.junit.experimental.categories.Category; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043 044/** 045 * Test the reading and writing of access permissions to and from zookeeper. 046 */ 047@Category({SecurityTests.class, LargeTests.class}) 048public class TestZKPermissionWatcher { 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestZKPermissionWatcher.class); 053 054 private static final Logger LOG = LoggerFactory.getLogger(TestZKPermissionWatcher.class); 055 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 056 private static TableAuthManager AUTH_A; 057 private static TableAuthManager AUTH_B; 058 private final static Abortable ABORTABLE = new Abortable() { 059 private final AtomicBoolean abort = new AtomicBoolean(false); 060 061 @Override 062 public void abort(String why, Throwable e) { 063 LOG.info(why, e); 064 abort.set(true); 065 } 066 067 @Override 068 public boolean isAborted() { 069 return abort.get(); 070 } 071 }; 072 073 private static TableName TEST_TABLE = 074 TableName.valueOf("perms_test"); 075 076 @BeforeClass 077 public static void beforeClass() throws Exception { 078 // setup configuration 079 Configuration conf = UTIL.getConfiguration(); 080 SecureTestUtil.enableSecurity(conf); 081 082 // start minicluster 083 UTIL.startMiniCluster(); 084 AUTH_A = TableAuthManager.getOrCreate(new ZKWatcher(conf, 085 "TestZKPermissionsWatcher_1", ABORTABLE), conf); 086 AUTH_B = TableAuthManager.getOrCreate(new ZKWatcher(conf, 087 "TestZKPermissionsWatcher_2", ABORTABLE), conf); 088 } 089 090 @AfterClass 091 public static void afterClass() throws Exception { 092 UTIL.shutdownMiniCluster(); 093 } 094 095 @Test 096 public void testPermissionsWatcher() throws Exception { 097 Configuration conf = UTIL.getConfiguration(); 098 User george = User.createUserForTesting(conf, "george", new String[] { }); 099 User hubert = User.createUserForTesting(conf, "hubert", new String[] { }); 100 101 assertFalse(AUTH_A.authorizeUser(george, TEST_TABLE, null, 102 TablePermission.Action.READ)); 103 assertFalse(AUTH_A.authorizeUser(george, TEST_TABLE, null, 104 TablePermission.Action.WRITE)); 105 assertFalse(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 106 TablePermission.Action.READ)); 107 assertFalse(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 108 TablePermission.Action.WRITE)); 109 110 assertFalse(AUTH_B.authorizeUser(george, TEST_TABLE, null, 111 TablePermission.Action.READ)); 112 assertFalse(AUTH_B.authorizeUser(george, TEST_TABLE, null, 113 TablePermission.Action.WRITE)); 114 assertFalse(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 115 TablePermission.Action.READ)); 116 assertFalse(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 117 TablePermission.Action.WRITE)); 118 119 // update ACL: george RW 120 List<TablePermission> acl = new ArrayList<>(1); 121 acl.add(new TablePermission(TEST_TABLE, null, TablePermission.Action.READ, 122 TablePermission.Action.WRITE)); 123 final long mtimeB = AUTH_B.getMTime(); 124 AUTH_A.setTableUserPermissions(george.getShortName(), TEST_TABLE, acl); 125 // Wait for the update to propagate 126 UTIL.waitFor(10000, 100, new Predicate<Exception>() { 127 @Override 128 public boolean evaluate() throws Exception { 129 return AUTH_B.getMTime() > mtimeB; 130 } 131 }); 132 Thread.sleep(1000); 133 134 // check it 135 assertTrue(AUTH_A.authorizeUser(george, TEST_TABLE, null, 136 TablePermission.Action.READ)); 137 assertTrue(AUTH_A.authorizeUser(george, TEST_TABLE, null, 138 TablePermission.Action.WRITE)); 139 assertTrue(AUTH_B.authorizeUser(george, TEST_TABLE, null, 140 TablePermission.Action.READ)); 141 assertTrue(AUTH_B.authorizeUser(george, TEST_TABLE, null, 142 TablePermission.Action.WRITE)); 143 assertFalse(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 144 TablePermission.Action.READ)); 145 assertFalse(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 146 TablePermission.Action.WRITE)); 147 assertFalse(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 148 TablePermission.Action.READ)); 149 assertFalse(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 150 TablePermission.Action.WRITE)); 151 152 // update ACL: hubert R 153 acl = new ArrayList<>(1); 154 acl.add(new TablePermission(TEST_TABLE, null, TablePermission.Action.READ)); 155 final long mtimeA = AUTH_A.getMTime(); 156 AUTH_B.setTableUserPermissions("hubert", TEST_TABLE, acl); 157 // Wait for the update to propagate 158 UTIL.waitFor(10000, 100, new Predicate<Exception>() { 159 @Override 160 public boolean evaluate() throws Exception { 161 return AUTH_A.getMTime() > mtimeA; 162 } 163 }); 164 Thread.sleep(1000); 165 166 // check it 167 assertTrue(AUTH_A.authorizeUser(george, TEST_TABLE, null, 168 TablePermission.Action.READ)); 169 assertTrue(AUTH_A.authorizeUser(george, TEST_TABLE, null, 170 TablePermission.Action.WRITE)); 171 assertTrue(AUTH_B.authorizeUser(george, TEST_TABLE, null, 172 TablePermission.Action.READ)); 173 assertTrue(AUTH_B.authorizeUser(george, TEST_TABLE, null, 174 TablePermission.Action.WRITE)); 175 assertTrue(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 176 TablePermission.Action.READ)); 177 assertFalse(AUTH_A.authorizeUser(hubert, TEST_TABLE, null, 178 TablePermission.Action.WRITE)); 179 assertTrue(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 180 TablePermission.Action.READ)); 181 assertFalse(AUTH_B.authorizeUser(hubert, TEST_TABLE, null, 182 TablePermission.Action.WRITE)); 183 } 184}