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