1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.DataInputStream;
30 import java.io.DataOutputStream;
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.concurrent.atomic.AtomicBoolean;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.hadoop.conf.Configuration;
39 import org.apache.hadoop.hbase.Abortable;
40 import org.apache.hadoop.hbase.HBaseTestingUtility;
41 import org.apache.hadoop.hbase.LargeTests;
42 import org.apache.hadoop.hbase.client.HBaseAdmin;
43 import org.apache.hadoop.hbase.client.HTable;
44 import org.apache.hadoop.hbase.client.Put;
45 import org.apache.hadoop.hbase.security.User;
46 import org.apache.hadoop.hbase.util.Bytes;
47 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
48 import org.junit.AfterClass;
49 import org.junit.BeforeClass;
50 import org.junit.Test;
51 import org.junit.experimental.categories.Category;
52
53 import com.google.common.collect.ArrayListMultimap;
54 import com.google.common.collect.ListMultimap;
55
56
57
58
59 @Category(LargeTests.class)
60 public class TestTablePermissions {
61 private static final Log LOG = LogFactory.getLog(TestTablePermissions.class);
62 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
63 private static ZooKeeperWatcher ZKW;
64 private final static Abortable ABORTABLE = new Abortable() {
65 private final AtomicBoolean abort = new AtomicBoolean(false);
66
67 @Override
68 public void abort(String why, Throwable e) {
69 LOG.info(why, e);
70 abort.set(true);
71 }
72
73 @Override
74 public boolean isAborted() {
75 return abort.get();
76 }
77 };
78
79 private static byte[] TEST_TABLE = Bytes.toBytes("perms_test");
80 private static byte[] TEST_TABLE2 = Bytes.toBytes("perms_test2");
81 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
82 private static byte[] TEST_QUALIFIER = Bytes.toBytes("col1");
83
84 @BeforeClass
85 public static void beforeClass() throws Exception {
86
87 Configuration conf = UTIL.getConfiguration();
88 SecureTestUtil.enableSecurity(conf);
89
90 UTIL.startMiniCluster();
91
92
93 UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME, 5000);
94
95 ZKW = new ZooKeeperWatcher(UTIL.getConfiguration(),
96 "TestTablePermissions", ABORTABLE);
97
98 UTIL.createTable(TEST_TABLE, TEST_FAMILY);
99 UTIL.createTable(TEST_TABLE2, TEST_FAMILY);
100 }
101
102 @AfterClass
103 public static void afterClass() throws Exception {
104 UTIL.shutdownMiniCluster();
105 }
106
107 @Test
108 public void testBasicWrite() throws Exception {
109 Configuration conf = UTIL.getConfiguration();
110
111 AccessControlLists.addUserPermission(conf,
112 new UserPermission(Bytes.toBytes("george"), TEST_TABLE, null, (byte[])null,
113 UserPermission.Action.READ, UserPermission.Action.WRITE));
114 AccessControlLists.addUserPermission(conf,
115 new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE, null, (byte[])null,
116 UserPermission.Action.READ));
117 AccessControlLists.addUserPermission(conf,
118 new UserPermission(Bytes.toBytes("humphrey"),
119 TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER,
120 UserPermission.Action.READ));
121
122
123 ListMultimap<String,TablePermission> perms =
124 AccessControlLists.getTablePermissions(conf, TEST_TABLE);
125 List<TablePermission> userPerms = perms.get("george");
126 assertNotNull("Should have permissions for george", userPerms);
127 assertEquals("Should have 1 permission for george", 1, userPerms.size());
128 TablePermission permission = userPerms.get(0);
129 assertTrue("Permission should be for " + TEST_TABLE,
130 Bytes.equals(TEST_TABLE, permission.getTable()));
131 assertNull("Column family should be empty", permission.getFamily());
132
133
134 assertNotNull(permission.getActions());
135 assertEquals(2, permission.getActions().length);
136 List<TablePermission.Action> actions = Arrays.asList(permission.getActions());
137 assertTrue(actions.contains(TablePermission.Action.READ));
138 assertTrue(actions.contains(TablePermission.Action.WRITE));
139
140 userPerms = perms.get("hubert");
141 assertNotNull("Should have permissions for hubert", userPerms);
142 assertEquals("Should have 1 permission for hubert", 1, userPerms.size());
143 permission = userPerms.get(0);
144 assertTrue("Permission should be for " + TEST_TABLE,
145 Bytes.equals(TEST_TABLE, permission.getTable()));
146 assertNull("Column family should be empty", permission.getFamily());
147
148
149 assertNotNull(permission.getActions());
150 assertEquals(1, permission.getActions().length);
151 actions = Arrays.asList(permission.getActions());
152 assertTrue(actions.contains(TablePermission.Action.READ));
153 assertFalse(actions.contains(TablePermission.Action.WRITE));
154
155 userPerms = perms.get("humphrey");
156 assertNotNull("Should have permissions for humphrey", userPerms);
157 assertEquals("Should have 1 permission for humphrey", 1, userPerms.size());
158 permission = userPerms.get(0);
159 assertTrue("Permission should be for " + TEST_TABLE,
160 Bytes.equals(TEST_TABLE, permission.getTable()));
161 assertTrue("Permission should be for family " + TEST_FAMILY,
162 Bytes.equals(TEST_FAMILY, permission.getFamily()));
163 assertTrue("Permission should be for qualifier " + TEST_QUALIFIER,
164 Bytes.equals(TEST_QUALIFIER, permission.getQualifier()));
165
166
167 assertNotNull(permission.getActions());
168 assertEquals(1, permission.getActions().length);
169 actions = Arrays.asList(permission.getActions());
170 assertTrue(actions.contains(TablePermission.Action.READ));
171 assertFalse(actions.contains(TablePermission.Action.WRITE));
172
173
174 AccessControlLists.addUserPermission(conf,
175 new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE2, null, (byte[])null,
176 TablePermission.Action.READ, TablePermission.Action.WRITE));
177
178
179 Map<byte[],ListMultimap<String,TablePermission>> allPerms =
180 AccessControlLists.loadAll(conf);
181 assertEquals("Full permission map should have entries for both test tables",
182 2, allPerms.size());
183
184 userPerms = allPerms.get(TEST_TABLE).get("hubert");
185 assertNotNull(userPerms);
186 assertEquals(1, userPerms.size());
187 permission = userPerms.get(0);
188 assertTrue(Bytes.equals(TEST_TABLE, permission.getTable()));
189 assertEquals(1, permission.getActions().length);
190 assertEquals(TablePermission.Action.READ, permission.getActions()[0]);
191
192 userPerms = allPerms.get(TEST_TABLE2).get("hubert");
193 assertNotNull(userPerms);
194 assertEquals(1, userPerms.size());
195 permission = userPerms.get(0);
196 assertTrue(Bytes.equals(TEST_TABLE2, permission.getTable()));
197 assertEquals(2, permission.getActions().length);
198 actions = Arrays.asList(permission.getActions());
199 assertTrue(actions.contains(TablePermission.Action.READ));
200 assertTrue(actions.contains(TablePermission.Action.WRITE));
201 }
202
203 @Test
204 public void testPersistence() throws Exception {
205 Configuration conf = UTIL.getConfiguration();
206 AccessControlLists.addUserPermission(conf,
207 new UserPermission(Bytes.toBytes("albert"), TEST_TABLE, null,
208 (byte[])null, TablePermission.Action.READ));
209 AccessControlLists.addUserPermission(conf,
210 new UserPermission(Bytes.toBytes("betty"), TEST_TABLE, null,
211 (byte[])null, TablePermission.Action.READ,
212 TablePermission.Action.WRITE));
213 AccessControlLists.addUserPermission(conf,
214 new UserPermission(Bytes.toBytes("clark"),
215 TEST_TABLE, TEST_FAMILY,
216 TablePermission.Action.READ));
217 AccessControlLists.addUserPermission(conf,
218 new UserPermission(Bytes.toBytes("dwight"),
219 TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER,
220 TablePermission.Action.WRITE));
221
222
223 ListMultimap<String,TablePermission> preperms =
224 AccessControlLists.getTablePermissions(conf, TEST_TABLE);
225
226 HTable table = new HTable(conf, TEST_TABLE);
227 table.put(new Put(Bytes.toBytes("row1"))
228 .add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes("v1")));
229 table.put(new Put(Bytes.toBytes("row2"))
230 .add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes("v2")));
231 HBaseAdmin admin = UTIL.getHBaseAdmin();
232 admin.split(TEST_TABLE);
233
234
235 Thread.sleep(10000);
236
237 ListMultimap<String,TablePermission> postperms =
238 AccessControlLists.getTablePermissions(conf, TEST_TABLE);
239
240 checkMultimapEqual(preperms, postperms);
241 }
242
243 @Test
244 public void testSerialization() throws Exception {
245 Configuration conf = UTIL.getConfiguration();
246 ListMultimap<String,TablePermission> permissions = ArrayListMultimap.create();
247 permissions.put("george", new TablePermission(TEST_TABLE, null,
248 TablePermission.Action.READ));
249 permissions.put("george", new TablePermission(TEST_TABLE, TEST_FAMILY,
250 TablePermission.Action.WRITE));
251 permissions.put("george", new TablePermission(TEST_TABLE2, null,
252 TablePermission.Action.READ));
253 permissions.put("hubert", new TablePermission(TEST_TABLE2, null,
254 TablePermission.Action.READ, TablePermission.Action.WRITE));
255
256 ByteArrayOutputStream bos = new ByteArrayOutputStream();
257 AccessControlLists.writePermissions(new DataOutputStream(bos),
258 permissions, conf);
259
260 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
261 ListMultimap<String,TablePermission> copy =
262 AccessControlLists.readPermissions(new DataInputStream(bis), conf);
263
264 checkMultimapEqual(permissions, copy);
265 }
266
267 public void checkMultimapEqual(ListMultimap<String,TablePermission> first,
268 ListMultimap<String,TablePermission> second) {
269 assertEquals(first.size(), second.size());
270 for (String key : first.keySet()) {
271 List<TablePermission> firstPerms = first.get(key);
272 List<TablePermission> secondPerms = second.get(key);
273 assertNotNull(secondPerms);
274 assertEquals(firstPerms.size(), secondPerms.size());
275 LOG.info("First permissions: "+firstPerms.toString());
276 LOG.info("Second permissions: "+secondPerms.toString());
277 for (TablePermission p : firstPerms) {
278 assertTrue("Permission "+p.toString()+" not found", secondPerms.contains(p));
279 }
280 }
281 }
282
283 @Test
284 public void testEquals() throws Exception {
285 TablePermission p1 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ);
286 TablePermission p2 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ);
287 assertTrue(p1.equals(p2));
288 assertTrue(p2.equals(p1));
289
290 p1 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ, TablePermission.Action.WRITE);
291 p2 = new TablePermission(TEST_TABLE, null, TablePermission.Action.WRITE, TablePermission.Action.READ);
292 assertTrue(p1.equals(p2));
293 assertTrue(p2.equals(p1));
294
295 p1 = new TablePermission(TEST_TABLE, TEST_FAMILY, TablePermission.Action.READ, TablePermission.Action.WRITE);
296 p2 = new TablePermission(TEST_TABLE, TEST_FAMILY, TablePermission.Action.WRITE, TablePermission.Action.READ);
297 assertTrue(p1.equals(p2));
298 assertTrue(p2.equals(p1));
299
300 p1 = new TablePermission(TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER, TablePermission.Action.READ, TablePermission.Action.WRITE);
301 p2 = new TablePermission(TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER, TablePermission.Action.WRITE, TablePermission.Action.READ);
302 assertTrue(p1.equals(p2));
303 assertTrue(p2.equals(p1));
304
305 p1 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ);
306 p2 = new TablePermission(TEST_TABLE, TEST_FAMILY, TablePermission.Action.READ);
307 assertFalse(p1.equals(p2));
308 assertFalse(p2.equals(p1));
309
310 p1 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ);
311 p2 = new TablePermission(TEST_TABLE, null, TablePermission.Action.WRITE);
312 assertFalse(p1.equals(p2));
313 assertFalse(p2.equals(p1));
314 p2 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ, TablePermission.Action.WRITE);
315 assertFalse(p1.equals(p2));
316 assertFalse(p2.equals(p1));
317
318 p1 = new TablePermission(TEST_TABLE, null, TablePermission.Action.READ);
319 p2 = new TablePermission(TEST_TABLE2, null, TablePermission.Action.READ);
320 assertFalse(p1.equals(p2));
321 assertFalse(p2.equals(p1));
322
323 p2 = new TablePermission(TEST_TABLE, null);
324 assertFalse(p1.equals(p2));
325 assertFalse(p2.equals(p1));
326 }
327
328 @Test
329 public void testGlobalPermission() throws Exception {
330 Configuration conf = UTIL.getConfiguration();
331
332
333 AccessControlLists.addUserPermission(conf,
334 new UserPermission(Bytes.toBytes("user1"),
335 Permission.Action.READ, Permission.Action.WRITE));
336 AccessControlLists.addUserPermission(conf,
337 new UserPermission(Bytes.toBytes("user2"),
338 Permission.Action.CREATE));
339 AccessControlLists.addUserPermission(conf,
340 new UserPermission(Bytes.toBytes("user3"),
341 Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.CREATE));
342
343 ListMultimap<String,TablePermission> perms = AccessControlLists.getTablePermissions(conf, null);
344 List<TablePermission> user1Perms = perms.get("user1");
345 assertEquals("Should have 1 permission for user1", 1, user1Perms.size());
346 assertEquals("user1 should have WRITE permission",
347 new Permission.Action[] { Permission.Action.READ, Permission.Action.WRITE },
348 user1Perms.get(0).getActions());
349
350 List<TablePermission> user2Perms = perms.get("user2");
351 assertEquals("Should have 1 permission for user2", 1, user2Perms.size());
352 assertEquals("user2 should have CREATE permission",
353 new Permission.Action[] { Permission.Action.CREATE },
354 user2Perms.get(0).getActions());
355
356 List<TablePermission> user3Perms = perms.get("user3");
357 assertEquals("Should have 1 permission for user3", 1, user3Perms.size());
358 assertEquals("user3 should have ADMIN, READ, CREATE permission",
359 new Permission.Action[] {
360 Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.CREATE
361 },
362 user3Perms.get(0).getActions());
363 }
364
365 @Test
366 public void testAuthManager() throws Exception {
367 Configuration conf = UTIL.getConfiguration();
368
369
370
371 TableAuthManager authManager = TableAuthManager.get(ZKW, conf);
372
373 User currentUser = User.getCurrent();
374 assertTrue(authManager.authorize(currentUser, Permission.Action.ADMIN));
375 for (int i=1; i<=50; i++) {
376 AccessControlLists.addUserPermission(conf, new UserPermission(Bytes.toBytes("testauth"+i),
377 Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.WRITE));
378
379 assertTrue("Failed current user auth check on iter "+i,
380 authManager.authorize(currentUser, Permission.Action.ADMIN));
381 }
382 }
383 }