1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.access;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.fail;
22
23 import java.security.PrivilegedExceptionAction;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.Coprocessor;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HColumnDescriptor;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.testclassification.MediumTests;
35 import org.apache.hadoop.hbase.TableNotFoundException;
36 import org.apache.hadoop.hbase.client.Admin;
37 import org.apache.hadoop.hbase.client.Connection;
38 import org.apache.hadoop.hbase.client.ConnectionFactory;
39 import org.apache.hadoop.hbase.client.Delete;
40 import org.apache.hadoop.hbase.client.Get;
41 import org.apache.hadoop.hbase.client.HTable;
42 import org.apache.hadoop.hbase.client.Increment;
43 import org.apache.hadoop.hbase.client.Put;
44 import org.apache.hadoop.hbase.client.Table;
45 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
46 import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
47 import org.apache.hadoop.hbase.security.User;
48 import org.apache.hadoop.hbase.util.Bytes;
49 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
50 import org.apache.hadoop.hbase.util.TestTableName;
51 import org.apache.hadoop.hbase.util.Threads;
52 import org.apache.log4j.Level;
53 import org.apache.log4j.Logger;
54 import org.junit.After;
55 import org.junit.AfterClass;
56 import org.junit.Before;
57 import org.junit.BeforeClass;
58 import org.junit.Rule;
59 import org.junit.Test;
60 import org.junit.experimental.categories.Category;
61
62 @Category(MediumTests.class)
63 public class TestCellACLWithMultipleVersions extends SecureTestUtil {
64 private static final Log LOG = LogFactory.getLog(TestCellACLWithMultipleVersions.class);
65
66 static {
67 Logger.getLogger(AccessController.class).setLevel(Level.TRACE);
68 Logger.getLogger(AccessControlFilter.class).setLevel(Level.TRACE);
69 Logger.getLogger(TableAuthManager.class).setLevel(Level.TRACE);
70 }
71
72 @Rule
73 public TestTableName TEST_TABLE = new TestTableName();
74 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
75 private static final byte[] TEST_FAMILY1 = Bytes.toBytes("f1");
76 private static final byte[] TEST_FAMILY2 = Bytes.toBytes("f2");
77 private static final byte[] TEST_ROW = Bytes.toBytes("cellpermtest");
78 private static final byte[] TEST_Q1 = Bytes.toBytes("q1");
79 private static final byte[] TEST_Q2 = Bytes.toBytes("q2");
80 private static final byte[] ZERO = Bytes.toBytes(0L);
81 private static final byte[] ONE = Bytes.toBytes(1L);
82 private static final byte[] TWO = Bytes.toBytes(2L);
83
84 private static Configuration conf;
85
86 private static User USER_OWNER;
87 private static User USER_OTHER;
88 private static User USER_OTHER2;
89
90 @BeforeClass
91 public static void setupBeforeClass() throws Exception {
92
93 conf = TEST_UTIL.getConfiguration();
94
95 enableSecurity(conf);
96
97 verifyConfiguration(conf);
98
99
100 conf.setBoolean(AccessControlConstants.CF_ATTRIBUTE_EARLY_OUT, false);
101
102 TEST_UTIL.startMiniCluster();
103 MasterCoprocessorHost cpHost = TEST_UTIL.getMiniHBaseCluster().getMaster()
104 .getMasterCoprocessorHost();
105 cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf);
106 AccessController ac = (AccessController)
107 cpHost.findCoprocessor(AccessController.class.getName());
108 cpHost.createEnvironment(AccessController.class, ac, Coprocessor.PRIORITY_HIGHEST, 1, conf);
109 RegionServerCoprocessorHost rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
110 .getRegionServerCoprocessorHost();
111 rsHost.createEnvironment(AccessController.class, ac, Coprocessor.PRIORITY_HIGHEST, 1, conf);
112
113
114 TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME);
115
116
117 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
118 USER_OTHER = User.createUserForTesting(conf, "other", new String[0]);
119 USER_OTHER2 = User.createUserForTesting(conf, "other2", new String[0]);
120 }
121
122 @AfterClass
123 public static void tearDownAfterClass() throws Exception {
124 TEST_UTIL.shutdownMiniCluster();
125 }
126
127 @Before
128 public void setUp() throws Exception {
129 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
130 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY1);
131 hcd.setMaxVersions(4);
132 htd.setOwner(USER_OWNER);
133 htd.addFamily(hcd);
134 hcd = new HColumnDescriptor(TEST_FAMILY2);
135 hcd.setMaxVersions(4);
136 htd.setOwner(USER_OWNER);
137 htd.addFamily(hcd);
138
139 try (Connection connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
140 try (Admin admin = connection.getAdmin()) {
141 admin.createTable(htd, new byte[][] { Bytes.toBytes("s") });
142 }
143 }
144 TEST_UTIL.waitTableEnabled(TEST_TABLE.getTableName());
145 LOG.info("Sleeping a second because of HBASE-12581");
146 Threads.sleep(1000);
147 }
148
149 @Test
150 public void testCellPermissionwithVersions() throws Exception {
151
152
153 verifyAllowed(new AccessTestAction() {
154 @Override
155 public Object run() throws Exception {
156 Table t = new HTable(conf, TEST_TABLE.getTableName());
157 try {
158 Put p;
159
160 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
161 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.WRITE));
162 t.put(p);
163
164 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
165 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.READ));
166 t.put(p);
167 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
168 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.WRITE));
169 t.put(p);
170 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
171 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.READ));
172 t.put(p);
173 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
174 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.WRITE));
175 t.put(p);
176 } finally {
177 t.close();
178 }
179 return null;
180 }
181 }, USER_OWNER);
182
183
184
185 AccessTestAction getQ1 = new AccessTestAction() {
186 @Override
187 public Object run() throws Exception {
188 Get get = new Get(TEST_ROW);
189 get.setMaxVersions(10);
190 Table t = new HTable(conf, TEST_TABLE.getTableName());
191 try {
192 return t.get(get).listCells();
193 } finally {
194 t.close();
195 }
196 }
197 };
198
199 AccessTestAction get2 = new AccessTestAction() {
200 @Override
201 public Object run() throws Exception {
202 Get get = new Get(TEST_ROW);
203 get.setMaxVersions(10);
204 Table t = new HTable(conf, TEST_TABLE.getTableName());
205 try {
206 return t.get(get).listCells();
207 } finally {
208 t.close();
209 }
210 }
211 };
212
213
214 verifyAllowed(USER_OTHER, getQ1, 2);
215
216
217
218 verifyAllowed(new AccessTestAction() {
219 @Override
220 public Object run() throws Exception {
221 Table t = new HTable(conf, TEST_TABLE.getTableName());
222 try {
223 Put p;
224 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
225 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.WRITE));
226 t.put(p);
227 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
228 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.READ));
229 t.put(p);
230 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1, ZERO);
231 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.WRITE));
232 t.put(p);
233 } finally {
234 t.close();
235 }
236 return null;
237 }
238 }, USER_OWNER);
239
240
241 verifyAllowed(USER_OTHER, get2, 1);
242 }
243
244 @Test
245 public void testCellPermissionsWithDeleteMutipleVersions() throws Exception {
246
247 final byte[] TEST_ROW1 = Bytes.toBytes("r1");
248 final byte[] TEST_ROW2 = Bytes.toBytes("r2");
249 final byte[] TEST_Q1 = Bytes.toBytes("q1");
250 final byte[] TEST_Q2 = Bytes.toBytes("q2");
251 final byte[] ZERO = Bytes.toBytes(0L);
252
253
254 final User user1 = User.createUserForTesting(conf, "user1", new String[0]);
255 final User user2 = User.createUserForTesting(conf, "user2", new String[0]);
256
257 verifyAllowed(new AccessTestAction() {
258 @Override
259 public Object run() throws Exception {
260 try (Connection connection = ConnectionFactory.createConnection(conf)) {
261 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
262
263 Put p = new Put(TEST_ROW1);
264 p.add(TEST_FAMILY1, TEST_Q1, ZERO);
265 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
266 p.setACL(user1.getShortName(), new Permission(Permission.Action.READ,
267 Permission.Action.WRITE));
268 t.put(p);
269
270 p = new Put(TEST_ROW2);
271 p.add(TEST_FAMILY1, TEST_Q1, ZERO);
272 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
273 p.setACL(user1.getShortName(), new Permission(Permission.Action.READ,
274 Permission.Action.WRITE));
275 t.put(p);
276 }
277 }
278 return null;
279 }
280 }, USER_OWNER);
281
282 verifyAllowed(new AccessTestAction() {
283 @Override
284 public Object run() throws Exception {
285 try (Connection connection = ConnectionFactory.createConnection(conf)) {
286 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
287
288 Put p = new Put(TEST_ROW1);
289 p.add(TEST_FAMILY1, TEST_Q1, ZERO);
290 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
291 Map<String, Permission> perms = new HashMap<String, Permission>();
292 perms.put(user1.getShortName(), new Permission(Permission.Action.READ,
293 Permission.Action.WRITE));
294 perms.put(user2.getShortName(), new Permission(Permission.Action.READ,
295 Permission.Action.WRITE));
296 p.setACL(perms);
297 t.put(p);
298
299 p = new Put(TEST_ROW2);
300 p.add(TEST_FAMILY1, TEST_Q1, ZERO);
301 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
302 p.setACL(perms);
303 t.put(p);
304 }
305 }
306 return null;
307 }
308 }, user1);
309
310
311
312 user1.runAs(new PrivilegedExceptionAction<Void>() {
313 @Override
314 public Void run() throws Exception {
315 try (Connection connection = ConnectionFactory.createConnection(conf)) {
316 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
317 Delete d = new Delete(TEST_ROW1);
318 d.deleteColumns(TEST_FAMILY1, TEST_Q1);
319 d.deleteColumns(TEST_FAMILY1, TEST_Q2);
320 t.delete(d);
321 }
322 }
323 return null;
324 }
325 });
326
327
328 user2.runAs(new PrivilegedExceptionAction<Void>() {
329 @Override
330 public Void run() throws Exception {
331 try (Connection connection = ConnectionFactory.createConnection(conf)) {
332 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
333 Delete d = new Delete(TEST_ROW2);
334 d.deleteColumns(TEST_FAMILY1, TEST_Q1);
335 d.deleteColumns(TEST_FAMILY1, TEST_Q2);
336 t.delete(d);
337 fail("user2 should not be allowed to delete the row");
338 } catch (Exception e) {
339
340 }
341 }
342 return null;
343 }
344 });
345
346 user1.runAs(new PrivilegedExceptionAction<Void>() {
347 @Override
348 public Void run() throws Exception {
349 try (Connection connection = ConnectionFactory.createConnection(conf)) {
350 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
351 Delete d = new Delete(TEST_ROW2);
352 d.deleteFamily(TEST_FAMILY1);
353 t.delete(d);
354 }
355 }
356 return null;
357 }
358 });
359 }
360
361
362 @Test
363 public void testDeleteWithFutureTimestamp() throws Exception {
364
365
366 verifyAllowed(new AccessTestAction() {
367 @Override
368 public Object run() throws Exception {
369 try (Connection connection = ConnectionFactory.createConnection(conf)) {
370 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
371
372 Put p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q2, ONE);
373 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.READ,
374 Permission.Action.WRITE));
375 t.put(p);
376 LOG.info("Stored at current time");
377
378 p = new Put(TEST_ROW).add(TEST_FAMILY1, TEST_Q1,
379 EnvironmentEdgeManager.currentTime() + 1000000, ZERO);
380 p.setACL(USER_OTHER.getShortName(), new Permission(Permission.Action.READ));
381 t.put(p);
382 }
383 }
384 return null;
385 }
386 }, USER_OWNER);
387
388
389
390 AccessTestAction getQ1 = new AccessTestAction() {
391 @Override
392 public Object run() throws Exception {
393 Get get = new Get(TEST_ROW).addColumn(TEST_FAMILY1, TEST_Q1);
394 try (Connection connection = ConnectionFactory.createConnection(conf)) {
395 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
396 return t.get(get).listCells();
397 }
398 }
399 }
400 };
401
402 AccessTestAction getQ2 = new AccessTestAction() {
403 @Override
404 public Object run() throws Exception {
405 Get get = new Get(TEST_ROW).addColumn(TEST_FAMILY1, TEST_Q2);
406 try (Connection connection = ConnectionFactory.createConnection(conf)) {
407 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
408 return t.get(get).listCells();
409 }
410 }
411 }
412 };
413
414 verifyAllowed(getQ1, USER_OWNER, USER_OTHER);
415 verifyAllowed(getQ2, USER_OWNER, USER_OTHER);
416
417
418
419
420
421 AccessTestAction deleteFamily = new AccessTestAction() {
422 @Override
423 public Object run() throws Exception {
424 Delete delete = new Delete(TEST_ROW).deleteFamily(TEST_FAMILY1);
425 try (Connection connection = ConnectionFactory.createConnection(conf)) {
426 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
427 t.delete(delete);
428 }
429 }
430 return null;
431 }
432 };
433
434 verifyAllowed(deleteFamily, USER_OTHER);
435
436
437
438 verifyAllowed(getQ1, USER_OWNER, USER_OTHER);
439
440
441
442 verifyDenied(getQ2, USER_OTHER);
443 }
444
445 @Test
446 public void testCellPermissionsWithDeleteWithUserTs() throws Exception {
447 USER_OWNER.runAs(new AccessTestAction() {
448 @Override
449 public Object run() throws Exception {
450 try (Connection connection = ConnectionFactory.createConnection(conf)) {
451 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
452
453 Put p = new Put(TEST_ROW);
454 p.add(TEST_FAMILY1, TEST_Q1, 123L, ZERO);
455 p.add(TEST_FAMILY1, TEST_Q2, 123L, ZERO);
456 Map<String, Permission> perms = new HashMap<String, Permission>();
457 perms.put(USER_OTHER.getShortName(), new Permission(Permission.Action.READ,
458 Permission.Action.WRITE));
459 perms.put(USER_OTHER2.getShortName(), new Permission(Permission.Action.READ,
460 Permission.Action.WRITE));
461 p.setACL(perms);
462 t.put(p);
463
464
465 p = new Put(TEST_ROW);
466 p.add(TEST_FAMILY1, TEST_Q1, 125L, ONE);
467 p.add(TEST_FAMILY1, TEST_Q2, 125L, ONE);
468 perms = new HashMap<String, Permission>();
469 perms.put(USER_OTHER.getShortName(), new Permission(Permission.Action.READ,
470 Permission.Action.WRITE));
471 p.setACL(perms);
472 t.put(p);
473
474
475 p = new Put(TEST_ROW);
476 p.add(TEST_FAMILY1, TEST_Q1, 127L, TWO);
477 p.add(TEST_FAMILY1, TEST_Q2, 127L, TWO);
478 perms = new HashMap<String, Permission>();
479 perms.put(USER_OTHER.getShortName(), new Permission(Permission.Action.READ,
480 Permission.Action.WRITE));
481 p.setACL(perms);
482 t.put(p);
483
484 return null;
485 }
486 }
487 }
488 });
489
490
491 USER_OTHER2.runAs(new AccessTestAction() {
492 @Override
493 public Object run() throws Exception {
494 try (Connection connection = ConnectionFactory.createConnection(conf)) {
495 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
496 Delete d = new Delete(TEST_ROW, 124L);
497 d.deleteColumns(TEST_FAMILY1, TEST_Q1);
498 t.delete(d);
499 }
500 }
501 return null;
502 }
503 });
504
505
506 USER_OTHER2.runAs(new AccessTestAction() {
507 @Override
508 public Object run() throws Exception {
509 try (Connection connection = ConnectionFactory.createConnection(conf)) {
510 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
511 Delete d = new Delete(TEST_ROW);
512 d.deleteColumns(TEST_FAMILY1, TEST_Q2, 124L);
513 t.delete(d);
514 }
515 }
516 return null;
517 }
518 });
519 }
520
521 @Test
522 public void testCellPermissionsWithDeleteExactVersion() throws Exception {
523 final byte[] TEST_ROW1 = Bytes.toBytes("r1");
524 final byte[] TEST_Q1 = Bytes.toBytes("q1");
525 final byte[] TEST_Q2 = Bytes.toBytes("q2");
526 final byte[] ZERO = Bytes.toBytes(0L);
527
528 final User user1 = User.createUserForTesting(conf, "user1", new String[0]);
529 final User user2 = User.createUserForTesting(conf, "user2", new String[0]);
530
531 verifyAllowed(new AccessTestAction() {
532 @Override
533 public Object run() throws Exception {
534 try (Connection connection = ConnectionFactory.createConnection(conf)) {
535 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
536 Map<String, Permission> permsU1andOwner = new HashMap<String, Permission>();
537 permsU1andOwner.put(user1.getShortName(), new Permission(Permission.Action.READ,
538 Permission.Action.WRITE));
539 permsU1andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
540 Permission.Action.WRITE));
541 Map<String, Permission> permsU2andOwner = new HashMap<String, Permission>();
542 permsU2andOwner.put(user2.getShortName(), new Permission(Permission.Action.READ,
543 Permission.Action.WRITE));
544 permsU2andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
545 Permission.Action.WRITE));
546 Put p = new Put(TEST_ROW1);
547 p.add(TEST_FAMILY1, TEST_Q1, 123, ZERO);
548 p.setACL(permsU1andOwner);
549 t.put(p);
550 p = new Put(TEST_ROW1);
551 p.add(TEST_FAMILY1, TEST_Q2, 123, ZERO);
552 p.setACL(permsU2andOwner);
553 t.put(p);
554 p = new Put(TEST_ROW1);
555 p.add(TEST_FAMILY2, TEST_Q1, 123, ZERO);
556 p.add(TEST_FAMILY2, TEST_Q2, 123, ZERO);
557 p.setACL(permsU2andOwner);
558 t.put(p);
559
560 p = new Put(TEST_ROW1);
561 p.add(TEST_FAMILY2, TEST_Q1, 125, ZERO);
562 p.add(TEST_FAMILY2, TEST_Q2, 125, ZERO);
563 p.setACL(permsU1andOwner);
564 t.put(p);
565
566 p = new Put(TEST_ROW1);
567 p.add(TEST_FAMILY1, TEST_Q1, 127, ZERO);
568 p.setACL(permsU2andOwner);
569 t.put(p);
570 p = new Put(TEST_ROW1);
571 p.add(TEST_FAMILY1, TEST_Q2, 127, ZERO);
572 p.setACL(permsU1andOwner);
573 t.put(p);
574 p = new Put(TEST_ROW1);
575 p.add(TEST_FAMILY2, TEST_Q1, 129, ZERO);
576 p.add(TEST_FAMILY2, TEST_Q2, 129, ZERO);
577 p.setACL(permsU1andOwner);
578 t.put(p);
579 }
580 }
581 return null;
582 }
583 }, USER_OWNER);
584
585
586
587 user1.runAs(new PrivilegedExceptionAction<Void>() {
588 @Override
589 public Void run() throws Exception {
590 try (Connection connection = ConnectionFactory.createConnection(conf)) {
591 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
592 Delete d = new Delete(TEST_ROW1);
593 d.deleteColumn(TEST_FAMILY1, TEST_Q1, 123);
594 d.deleteColumn(TEST_FAMILY1, TEST_Q2);
595 d.deleteFamilyVersion(TEST_FAMILY2, 125);
596 t.delete(d);
597 }
598 }
599 return null;
600 }
601 });
602
603 user2.runAs(new PrivilegedExceptionAction<Void>() {
604 @Override
605 public Void run() throws Exception {
606 try (Connection connection = ConnectionFactory.createConnection(conf)) {
607 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
608 Delete d = new Delete(TEST_ROW1, 127);
609 d.deleteColumns(TEST_FAMILY1, TEST_Q1);
610 d.deleteColumns(TEST_FAMILY1, TEST_Q2);
611 d.deleteFamily(TEST_FAMILY2, 129);
612 t.delete(d);
613 fail("user2 can not do the delete");
614 } catch (Exception e) {
615
616 }
617 }
618 return null;
619 }
620 });
621 }
622
623 @Test
624 public void testCellPermissionsForIncrementWithMultipleVersions() throws Exception {
625 final byte[] TEST_ROW1 = Bytes.toBytes("r1");
626 final byte[] TEST_Q1 = Bytes.toBytes("q1");
627 final byte[] TEST_Q2 = Bytes.toBytes("q2");
628 final byte[] ZERO = Bytes.toBytes(0L);
629
630 final User user1 = User.createUserForTesting(conf, "user1", new String[0]);
631 final User user2 = User.createUserForTesting(conf, "user2", new String[0]);
632
633 verifyAllowed(new AccessTestAction() {
634 @Override
635 public Object run() throws Exception {
636 try (Connection connection = ConnectionFactory.createConnection(conf)) {
637 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
638 Map<String, Permission> permsU1andOwner = new HashMap<String, Permission>();
639 permsU1andOwner.put(user1.getShortName(), new Permission(Permission.Action.READ,
640 Permission.Action.WRITE));
641 permsU1andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
642 Permission.Action.WRITE));
643 Map<String, Permission> permsU2andOwner = new HashMap<String, Permission>();
644 permsU2andOwner.put(user2.getShortName(), new Permission(Permission.Action.READ,
645 Permission.Action.WRITE));
646 permsU2andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
647 Permission.Action.WRITE));
648 Put p = new Put(TEST_ROW1);
649 p.add(TEST_FAMILY1, TEST_Q1, 123, ZERO);
650 p.setACL(permsU1andOwner);
651 t.put(p);
652 p = new Put(TEST_ROW1);
653 p.add(TEST_FAMILY1, TEST_Q2, 123, ZERO);
654 p.setACL(permsU2andOwner);
655 t.put(p);
656
657 p = new Put(TEST_ROW1);
658 p.add(TEST_FAMILY1, TEST_Q1, 127, ZERO);
659 p.setACL(permsU2andOwner);
660 t.put(p);
661 p = new Put(TEST_ROW1);
662 p.add(TEST_FAMILY1, TEST_Q2, 127, ZERO);
663 p.setACL(permsU1andOwner);
664 t.put(p);
665 }
666 }
667 return null;
668 }
669 }, USER_OWNER);
670
671
672 user1.runAs(new PrivilegedExceptionAction<Void>() {
673 @Override
674 public Void run() throws Exception {
675 try (Connection connection = ConnectionFactory.createConnection(conf)) {
676 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
677 Increment inc = new Increment(TEST_ROW1);
678 inc.setTimeRange(0, 123);
679 inc.addColumn(TEST_FAMILY1, TEST_Q1, 2L);
680 t.increment(inc);
681 t.incrementColumnValue(TEST_ROW1, TEST_FAMILY1, TEST_Q2, 1L);
682 }
683 }
684 return null;
685 }
686 });
687
688 user2.runAs(new PrivilegedExceptionAction<Void>() {
689 @Override
690 public Void run() throws Exception {
691 try (Connection connection = ConnectionFactory.createConnection(conf)) {
692 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
693 Increment inc = new Increment(TEST_ROW1);
694 inc.setTimeRange(0, 127);
695 inc.addColumn(TEST_FAMILY1, TEST_Q2, 2L);
696 t.increment(inc);
697 fail();
698 } catch (Exception e) {
699
700 }
701 }
702 return null;
703 }
704 });
705 }
706
707 @Test
708 public void testCellPermissionsForPutWithMultipleVersions() throws Exception {
709 final byte[] TEST_ROW1 = Bytes.toBytes("r1");
710 final byte[] TEST_Q1 = Bytes.toBytes("q1");
711 final byte[] TEST_Q2 = Bytes.toBytes("q2");
712 final byte[] ZERO = Bytes.toBytes(0L);
713
714 final User user1 = User.createUserForTesting(conf, "user1", new String[0]);
715 final User user2 = User.createUserForTesting(conf, "user2", new String[0]);
716
717 verifyAllowed(new AccessTestAction() {
718 @Override
719 public Object run() throws Exception {
720 try (Connection connection = ConnectionFactory.createConnection(conf)) {
721 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
722 Map<String, Permission> permsU1andOwner = new HashMap<String, Permission>();
723 permsU1andOwner.put(user1.getShortName(), new Permission(Permission.Action.READ,
724 Permission.Action.WRITE));
725 permsU1andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
726 Permission.Action.WRITE));
727 Map<String, Permission> permsU2andOwner = new HashMap<String, Permission>();
728 permsU2andOwner.put(user2.getShortName(), new Permission(Permission.Action.READ,
729 Permission.Action.WRITE));
730 permsU2andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
731 Permission.Action.WRITE));
732 Put p = new Put(TEST_ROW1);
733 p.add(TEST_FAMILY1, TEST_Q1, 123, ZERO);
734 p.setACL(permsU1andOwner);
735 t.put(p);
736 p = new Put(TEST_ROW1);
737 p.add(TEST_FAMILY1, TEST_Q2, 123, ZERO);
738 p.setACL(permsU2andOwner);
739 t.put(p);
740
741 p = new Put(TEST_ROW1);
742 p.add(TEST_FAMILY1, TEST_Q1, 127, ZERO);
743 p.setACL(permsU2andOwner);
744 t.put(p);
745 p = new Put(TEST_ROW1);
746 p.add(TEST_FAMILY1, TEST_Q2, 127, ZERO);
747 p.setACL(permsU1andOwner);
748 t.put(p);
749 }
750 }
751 return null;
752 }
753 }, USER_OWNER);
754
755
756
757
758 user1.runAs(new PrivilegedExceptionAction<Void>() {
759 @Override
760 public Void run() throws Exception {
761 try (Connection connection = ConnectionFactory.createConnection(conf)) {
762 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
763 Put p = new Put(TEST_ROW1);
764 p.add(TEST_FAMILY1, TEST_Q1, 125, ZERO);
765 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
766 p.setACL(user2.getShortName(), new Permission(Permission.Action.READ,
767 Permission.Action.WRITE));
768 t.put(p);
769 }
770 }
771 return null;
772 }
773 });
774
775
776 user2.runAs(new PrivilegedExceptionAction<Void>() {
777 @Override
778 public Void run() throws Exception {
779 try (Connection connection = ConnectionFactory.createConnection(conf)) {
780 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
781 Put p = new Put(TEST_ROW1);
782
783 p.add(TEST_FAMILY1, TEST_Q1, 124, ZERO);
784 p.add(TEST_FAMILY1, TEST_Q2, ZERO);
785 t.put(p);
786 fail();
787 } catch (Exception e) {
788
789 }
790 }
791 return null;
792 }
793 });
794 }
795
796 @Test
797 public void testCellPermissionsForCheckAndDelete() throws Exception {
798 final byte[] TEST_ROW1 = Bytes.toBytes("r1");
799 final byte[] ZERO = Bytes.toBytes(0L);
800
801 final User user1 = User.createUserForTesting(conf, "user1", new String[0]);
802 final User user2 = User.createUserForTesting(conf, "user2", new String[0]);
803
804 verifyAllowed(new AccessTestAction() {
805 @Override
806 public Object run() throws Exception {
807 try (Connection connection = ConnectionFactory.createConnection(conf)) {
808 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
809 Map<String, Permission> permsU1andOwner = new HashMap<String, Permission>();
810 permsU1andOwner.put(user1.getShortName(), new Permission(Permission.Action.READ,
811 Permission.Action.WRITE));
812 permsU1andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
813 Permission.Action.WRITE));
814 Map<String, Permission> permsU1andU2andOwner = new HashMap<String, Permission>();
815 permsU1andU2andOwner.put(user1.getShortName(), new Permission(Permission.Action.READ,
816 Permission.Action.WRITE));
817 permsU1andU2andOwner.put(user2.getShortName(), new Permission(Permission.Action.READ,
818 Permission.Action.WRITE));
819 permsU1andU2andOwner.put(USER_OWNER.getShortName(), new Permission(Permission.Action.READ,
820 Permission.Action.WRITE));
821 Map<String, Permission> permsU1andU2 = new HashMap<String, Permission>();
822 permsU1andU2.put(user1.getShortName(), new Permission(Permission.Action.READ,
823 Permission.Action.WRITE));
824 permsU1andU2.put(user2.getShortName(), new Permission(Permission.Action.READ,
825 Permission.Action.WRITE));
826
827 Put p = new Put(TEST_ROW1);
828 p.add(TEST_FAMILY1, TEST_Q1, 120, ZERO);
829 p.add(TEST_FAMILY1, TEST_Q2, 120, ZERO);
830 p.setACL(permsU1andU2andOwner);
831 t.put(p);
832
833 p = new Put(TEST_ROW1);
834 p.add(TEST_FAMILY1, TEST_Q1, 123, ZERO);
835 p.add(TEST_FAMILY1, TEST_Q2, 123, ZERO);
836 p.setACL(permsU1andOwner);
837 t.put(p);
838
839 p = new Put(TEST_ROW1);
840 p.add(TEST_FAMILY1, TEST_Q1, 127, ZERO);
841 p.setACL(permsU1andU2);
842 t.put(p);
843
844 p = new Put(TEST_ROW1);
845 p.add(TEST_FAMILY1, TEST_Q2, 127, ZERO);
846 p.setACL(user2.getShortName(), new Permission(Permission.Action.READ));
847 t.put(p);
848 }
849 }
850 return null;
851 }
852 }, USER_OWNER);
853
854
855
856 user1.runAs(new PrivilegedExceptionAction<Void>() {
857 @Override
858 public Void run() throws Exception {
859 try (Connection connection = ConnectionFactory.createConnection(conf)) {
860 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
861 Delete d = new Delete(TEST_ROW1);
862 d.deleteColumns(TEST_FAMILY1, TEST_Q1, 120);
863 t.checkAndDelete(TEST_ROW1, TEST_FAMILY1, TEST_Q1, ZERO, d);
864 }
865 }
866 return null;
867 }
868 });
869
870
871 user2.runAs(new PrivilegedExceptionAction<Void>() {
872 @Override
873 public Void run() throws Exception {
874 try (Connection connection = ConnectionFactory.createConnection(conf)) {
875 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
876 Delete d = new Delete(TEST_ROW1);
877 d.deleteColumns(TEST_FAMILY1, TEST_Q1);
878 t.checkAndDelete(TEST_ROW1, TEST_FAMILY1, TEST_Q1, ZERO, d);
879 fail("user2 should not be allowed to do checkAndDelete");
880 } catch (Exception e) {
881 }
882 }
883 return null;
884 }
885 });
886
887
888
889 user2.runAs(new PrivilegedExceptionAction<Void>() {
890 @Override
891 public Void run() throws Exception {
892 try (Connection connection = ConnectionFactory.createConnection(conf)) {
893 try (Table t = connection.getTable(TEST_TABLE.getTableName())) {
894 Delete d = new Delete(TEST_ROW1);
895 d.deleteColumn(TEST_FAMILY1, TEST_Q2, 120);
896 t.checkAndDelete(TEST_ROW1, TEST_FAMILY1, TEST_Q2, ZERO, d);
897 }
898 }
899 return null;
900 }
901 });
902 }
903
904 @After
905 public void tearDown() throws Exception {
906
907 try {
908 TEST_UTIL.deleteTable(TEST_TABLE.getTableName());
909 } catch (TableNotFoundException ex) {
910
911 LOG.info("Test deleted table " + TEST_TABLE.getTableName());
912 }
913 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size());
914 }
915 }