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
25 import java.security.PrivilegedExceptionAction;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.UUID;
29
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.testclassification.LargeTests;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.HTable;
36 import org.apache.hadoop.hbase.client.Put;
37 import org.apache.hadoop.hbase.client.Result;
38 import org.apache.hadoop.hbase.client.ResultScanner;
39 import org.apache.hadoop.hbase.client.Scan;
40 import org.apache.hadoop.hbase.client.Table;
41 import org.apache.hadoop.hbase.security.User;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.junit.AfterClass;
44 import org.junit.Before;
45 import org.junit.BeforeClass;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.experimental.categories.Category;
49 import org.junit.rules.TestName;
50
51 @Category(LargeTests.class)
52 public class TestAccessControlFilter extends SecureTestUtil {
53 @Rule public TestName name = new TestName();
54 private static HBaseTestingUtility TEST_UTIL;
55
56 private static User READER;
57 private static User LIMITED;
58 private static User DENIED;
59
60 private static TableName TABLE;
61 private static byte[] FAMILY = Bytes.toBytes("f1");
62 private static byte[] PRIVATE_COL = Bytes.toBytes("private");
63 private static byte[] PUBLIC_COL = Bytes.toBytes("public");
64
65 @Before
66 public void setup () {
67 TABLE = TableName.valueOf(name.getMethodName());
68 }
69
70 @BeforeClass
71 public static void setupBeforeClass() throws Exception {
72 TEST_UTIL = new HBaseTestingUtility();
73 Configuration conf = TEST_UTIL.getConfiguration();
74
75 conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10);
76 enableSecurity(conf);
77 verifyConfiguration(conf);
78
79
80 conf.setBoolean(AccessControlConstants.CF_ATTRIBUTE_EARLY_OUT, false);
81
82 TEST_UTIL.startMiniCluster();
83 TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME.getName(), 50000);
84
85 READER = User.createUserForTesting(conf, "reader", new String[0]);
86 LIMITED = User.createUserForTesting(conf, "limited", new String[0]);
87 DENIED = User.createUserForTesting(conf, "denied", new String[0]);
88 }
89
90 @AfterClass
91 public static void tearDownAfterClass() throws Exception {
92 TEST_UTIL.shutdownMiniCluster();
93 }
94
95 @Test (timeout=180000)
96 public void testQualifierAccess() throws Exception {
97 final Table table = createTable(TEST_UTIL, TABLE, new byte[][] { FAMILY });
98 try {
99 doQualifierAccess(table);
100 } finally {
101 table.close();
102 }
103 }
104
105 private void doQualifierAccess(final Table table) throws Exception {
106
107 SecureTestUtil.grantOnTable(TEST_UTIL, READER.getShortName(), TABLE, null, null,
108 Permission.Action.READ);
109 SecureTestUtil.grantOnTable(TEST_UTIL, LIMITED.getShortName(), TABLE, FAMILY, PUBLIC_COL,
110 Permission.Action.READ);
111
112
113 List<Put> puts = new ArrayList<Put>(100);
114 for (int i=0; i<100; i++) {
115 Put p = new Put(Bytes.toBytes(i));
116 p.add(FAMILY, PRIVATE_COL, Bytes.toBytes("secret "+i));
117 p.add(FAMILY, PUBLIC_COL, Bytes.toBytes("info "+i));
118 puts.add(p);
119 }
120 table.put(puts);
121
122
123 READER.runAs(new PrivilegedExceptionAction<Object>() {
124 public Object run() throws Exception {
125 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
126
127 conf.set("testkey", UUID.randomUUID().toString());
128 Table t = new HTable(conf, TABLE);
129 try {
130 ResultScanner rs = t.getScanner(new Scan());
131 int rowcnt = 0;
132 for (Result r : rs) {
133 rowcnt++;
134 int rownum = Bytes.toInt(r.getRow());
135 assertTrue(r.containsColumn(FAMILY, PRIVATE_COL));
136 assertEquals("secret "+rownum, Bytes.toString(r.getValue(FAMILY, PRIVATE_COL)));
137 assertTrue(r.containsColumn(FAMILY, PUBLIC_COL));
138 assertEquals("info "+rownum, Bytes.toString(r.getValue(FAMILY, PUBLIC_COL)));
139 }
140 assertEquals("Expected 100 rows returned", 100, rowcnt);
141 return null;
142 } finally {
143 t.close();
144 }
145 }
146 });
147
148
149 LIMITED.runAs(new PrivilegedExceptionAction<Object>() {
150 public Object run() throws Exception {
151 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
152
153 conf.set("testkey", UUID.randomUUID().toString());
154 Table t = new HTable(conf, TABLE);
155 try {
156 ResultScanner rs = t.getScanner(new Scan());
157 int rowcnt = 0;
158 for (Result r : rs) {
159 rowcnt++;
160 int rownum = Bytes.toInt(r.getRow());
161 assertFalse(r.containsColumn(FAMILY, PRIVATE_COL));
162 assertTrue(r.containsColumn(FAMILY, PUBLIC_COL));
163 assertEquals("info " + rownum, Bytes.toString(r.getValue(FAMILY, PUBLIC_COL)));
164 }
165 assertEquals("Expected 100 rows returned", 100, rowcnt);
166 return null;
167 } finally {
168 t.close();
169 }
170 }
171 });
172
173
174 DENIED.runAs(new PrivilegedExceptionAction<Object>(){
175 public Object run() throws Exception {
176 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
177
178 conf.set("testkey", UUID.randomUUID().toString());
179 Table t = new HTable(conf, TABLE);
180 try {
181 ResultScanner rs = t.getScanner(new Scan());
182 int rowcnt = 0;
183 for (Result r : rs) {
184 rowcnt++;
185 int rownum = Bytes.toInt(r.getRow());
186 assertFalse(r.containsColumn(FAMILY, PRIVATE_COL));
187 assertTrue(r.containsColumn(FAMILY, PUBLIC_COL));
188 assertEquals("info " + rownum, Bytes.toString(r.getValue(FAMILY, PUBLIC_COL)));
189 }
190 assertEquals("Expected 0 rows returned", 0, rowcnt);
191 return null;
192 } finally {
193 t.close();
194 }
195 }
196 });
197 }
198 }