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