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.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.security.PrivilegedExceptionAction;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.UUID;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.LargeTests;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.client.Put;
38 import org.apache.hadoop.hbase.client.Result;
39 import org.apache.hadoop.hbase.client.ResultScanner;
40 import org.apache.hadoop.hbase.client.Scan;
41 import org.apache.hadoop.hbase.security.AccessDeniedException;
42 import org.apache.hadoop.hbase.security.User;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.junit.AfterClass;
45 import org.junit.BeforeClass;
46 import org.junit.Test;
47 import org.junit.experimental.categories.Category;
48
49 @Category(LargeTests.class)
50 public class TestAccessControlFilter {
51 private static Log LOG = LogFactory.getLog(TestAccessControlFilter.class);
52 private static HBaseTestingUtility TEST_UTIL;
53
54 private static User ADMIN;
55 private static User READER;
56 private static User LIMITED;
57 private static User DENIED;
58
59 private static byte[] TABLE = Bytes.toBytes("testtable");
60 private static byte[] FAMILY = Bytes.toBytes("f1");
61 private static byte[] PRIVATE_COL = Bytes.toBytes("private");
62 private static byte[] PUBLIC_COL = Bytes.toBytes("public");
63
64 @BeforeClass
65 public static void setupBeforeClass() throws Exception {
66 TEST_UTIL = new HBaseTestingUtility();
67 Configuration conf = TEST_UTIL.getConfiguration();
68 SecureTestUtil.enableSecurity(conf);
69 String baseuser = User.getCurrent().getShortName();
70 conf.set("hbase.superuser", conf.get("hbase.superuser", "") +
71 String.format(",%s.hfs.0,%s.hfs.1,%s.hfs.2", baseuser, baseuser, baseuser));
72 TEST_UTIL.startMiniCluster();
73 TEST_UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME, 5000);
74
75 ADMIN = User.createUserForTesting(conf, "admin", new String[]{"supergroup"});
76 READER = User.createUserForTesting(conf, "reader", new String[0]);
77 LIMITED = User.createUserForTesting(conf, "limited", new String[0]);
78 DENIED = User.createUserForTesting(conf, "denied", new String[0]);
79 }
80
81 @AfterClass
82 public static void tearDownAfterClass() throws Exception {
83 TEST_UTIL.shutdownMiniCluster();
84 }
85
86 @Test
87 public void testQualifierAccess() throws Exception {
88 final HTable table = TEST_UTIL.createTable(TABLE, FAMILY);
89
90
91 ADMIN.runAs(new PrivilegedExceptionAction<Object>() {
92 @Override
93 public Object run() throws Exception {
94 HTable aclmeta = new HTable(TEST_UTIL.getConfiguration(),
95 AccessControlLists.ACL_TABLE_NAME);
96 AccessControllerProtocol acls = aclmeta.coprocessorProxy(
97 AccessControllerProtocol.class, Bytes.toBytes("testtable"));
98 UserPermission perm = new UserPermission(Bytes.toBytes(READER.getShortName()),
99 TABLE, null, Permission.Action.READ);
100 acls.grant(perm);
101 perm = new UserPermission(Bytes.toBytes(LIMITED.getShortName()),
102 TABLE, FAMILY, PUBLIC_COL, Permission.Action.READ);
103 acls.grant(perm);
104 return null;
105 }
106 });
107
108
109 List<Put> puts = new ArrayList<Put>(100);
110 for (int i=0; i<100; i++) {
111 Put p = new Put(Bytes.toBytes(i));
112 p.add(FAMILY, PRIVATE_COL, Bytes.toBytes("secret "+i));
113 p.add(FAMILY, PUBLIC_COL, Bytes.toBytes("info "+i));
114 puts.add(p);
115 }
116 table.put(puts);
117
118
119 READER.runAs(new PrivilegedExceptionAction<Object>() {
120 public Object run() throws Exception {
121 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
122
123 conf.set("testkey", UUID.randomUUID().toString());
124 HTable t = new HTable(conf, TABLE);
125 ResultScanner rs = t.getScanner(new Scan());
126 int rowcnt = 0;
127 for (Result r : rs) {
128 rowcnt++;
129 int rownum = Bytes.toInt(r.getRow());
130 assertTrue(r.containsColumn(FAMILY, PRIVATE_COL));
131 assertEquals("secret "+rownum, Bytes.toString(r.getValue(FAMILY, PRIVATE_COL)));
132 assertTrue(r.containsColumn(FAMILY, PUBLIC_COL));
133 assertEquals("info "+rownum, Bytes.toString(r.getValue(FAMILY, PUBLIC_COL)));
134 }
135 assertEquals("Expected 100 rows returned", 100, rowcnt);
136 return null;
137 }
138 });
139
140
141 LIMITED.runAs(new PrivilegedExceptionAction<Object>() {
142 public Object run() throws Exception {
143 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
144
145 conf.set("testkey", UUID.randomUUID().toString());
146 HTable t = new HTable(conf, TABLE);
147 ResultScanner rs = t.getScanner(new Scan());
148 int rowcnt = 0;
149 for (Result r : rs) {
150 rowcnt++;
151 int rownum = Bytes.toInt(r.getRow());
152 assertFalse(r.containsColumn(FAMILY, PRIVATE_COL));
153 assertTrue(r.containsColumn(FAMILY, PUBLIC_COL));
154 assertEquals("info " + rownum, Bytes.toString(r.getValue(FAMILY, PUBLIC_COL)));
155 }
156 assertEquals("Expected 100 rows returned", 100, rowcnt);
157 return null;
158 }
159 });
160
161
162 DENIED.runAs(new PrivilegedExceptionAction(){
163 public Object run() throws Exception {
164 try {
165 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
166
167 conf.set("testkey", UUID.randomUUID().toString());
168 HTable t = new HTable(conf, TABLE);
169 ResultScanner rs = t.getScanner(new Scan());
170 fail("Attempt to open scanner should have been denied");
171 } catch (AccessDeniedException ade) {
172
173 }
174 return null;
175 }
176 });
177 }
178 }