1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.visibility;
19
20 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
21 import static org.apache.hadoop.hbase.security.visibility.VisibilityUtils.SYSTEM_LABEL;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.fail;
26
27 import java.io.IOException;
28 import java.security.PrivilegedExceptionAction;
29 import java.util.List;
30 import java.util.concurrent.atomic.AtomicBoolean;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
37 import org.apache.hadoop.hbase.client.HTable;
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.protobuf.ProtobufUtil;
42 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
43 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair;
44 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.ListLabelsResponse;
45 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
46 import org.apache.hadoop.hbase.security.User;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
49 import org.apache.hadoop.hbase.util.Threads;
50 import org.junit.Assert;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.junit.experimental.categories.Category;
54
55 import com.google.protobuf.ByteString;
56
57 @Category(MediumTests.class)
58 public class TestVisibilityLabelsWithDefaultVisLabelService extends TestVisibilityLabels {
59 final Log LOG = LogFactory.getLog(getClass());
60
61 @BeforeClass
62 public static void setupBeforeClass() throws Exception {
63
64 conf = TEST_UTIL.getConfiguration();
65 conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
66 conf.setBoolean("hbase.online.schema.update.enable", true);
67 VisibilityTestUtil.enableVisiblityLabels(conf);
68 conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
69 ScanLabelGenerator.class);
70 conf.set("hbase.superuser", "admin");
71 TEST_UTIL.startMiniCluster(2);
72 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
73 USER1 = User.createUserForTesting(conf, "user1", new String[] {});
74
75
76 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
77 addLabels();
78 }
79
80 @Test
81 public void testAddLabels() throws Throwable {
82 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
83 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
84 public VisibilityLabelsResponse run() throws Exception {
85 String[] labels = { "L1", SECRET, "L2", "invalid~", "L3" };
86 VisibilityLabelsResponse response = null;
87 try {
88 response = VisibilityClient.addLabels(conf, labels);
89 } catch (Throwable e) {
90 fail("Should not have thrown exception");
91 }
92 List<RegionActionResult> resultList = response.getResultList();
93 assertEquals(5, resultList.size());
94 assertTrue(resultList.get(0).getException().getValue().isEmpty());
95 assertEquals("org.apache.hadoop.hbase.DoNotRetryIOException", resultList.get(1)
96 .getException().getName());
97 assertTrue(Bytes.toString(resultList.get(1).getException().getValue().toByteArray())
98 .contains(
99 "org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException: "
100 + "Label 'secret' already exists"));
101 assertTrue(resultList.get(2).getException().getValue().isEmpty());
102 assertTrue(resultList.get(3).getException().getValue().isEmpty());
103 assertTrue(resultList.get(4).getException().getValue().isEmpty());
104 return null;
105 }
106 };
107 SUPERUSER.runAs(action);
108 }
109
110 @Test(timeout = 60 * 1000)
111 public void testAddVisibilityLabelsOnRSRestart() throws Exception {
112 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
113 .getRegionServerThreads();
114 for (RegionServerThread rsThread : regionServerThreads) {
115 rsThread.getRegionServer().abort("Aborting ");
116 }
117
118 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
119 waitForLabelsRegionAvailability(rs.getRegionServer());
120 final AtomicBoolean vcInitialized = new AtomicBoolean(true);
121 do {
122 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
123 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
124 public VisibilityLabelsResponse run() throws Exception {
125 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, "ABC", "XYZ" };
126 try {
127 VisibilityLabelsResponse resp = VisibilityClient.addLabels(conf, labels);
128 List<RegionActionResult> results = resp.getResultList();
129 if (results.get(0).hasException()) {
130 NameBytesPair pair = results.get(0).getException();
131 Throwable t = ProtobufUtil.toException(pair);
132 LOG.debug("Got exception writing labels", t);
133 if (t instanceof VisibilityControllerNotReadyException) {
134 vcInitialized.set(false);
135 LOG.warn("VisibilityController was not yet initialized");
136 Threads.sleep(10);
137 } else {
138 vcInitialized.set(true);
139 }
140 } else LOG.debug("new labels added: " + resp);
141 } catch (Throwable t) {
142 throw new IOException(t);
143 }
144 return null;
145 }
146 };
147 SUPERUSER.runAs(action);
148 } while (!vcInitialized.get());
149
150 Scan s = new Scan();
151 s.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
152 HTable ht = new HTable(conf, LABELS_TABLE_NAME.getName());
153 int i = 0;
154 try {
155 ResultScanner scanner = ht.getScanner(s);
156 while (true) {
157 Result next = scanner.next();
158 if (next == null) {
159 break;
160 }
161 i++;
162 }
163 } finally {
164 if (ht != null) {
165 ht.close();
166 }
167 }
168
169 Assert.assertEquals("The count should be 13", 13, i);
170 }
171
172 @Test
173 public void testListLabels() throws Throwable {
174 PrivilegedExceptionAction<ListLabelsResponse> action =
175 new PrivilegedExceptionAction<ListLabelsResponse>() {
176 public ListLabelsResponse run() throws Exception {
177 ListLabelsResponse response = null;
178 try {
179 response = VisibilityClient.listLabels(conf, null);
180 } catch (Throwable e) {
181 fail("Should not have thrown exception");
182 }
183
184
185
186
187
188 List<ByteString> labels = response.getLabelList();
189 assertEquals(12, labels.size());
190 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
191 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
192 assertTrue(labels.contains(ByteString.copyFrom(CONFIDENTIAL.getBytes())));
193 assertTrue(labels.contains(ByteString.copyFrom("ABC".getBytes())));
194 assertTrue(labels.contains(ByteString.copyFrom("XYZ".getBytes())));
195 assertFalse(labels.contains(ByteString.copyFrom(SYSTEM_LABEL.getBytes())));
196 return null;
197 }
198 };
199 SUPERUSER.runAs(action);
200 }
201
202 @Test
203 public void testListLabelsWithRegEx() throws Throwable {
204 PrivilegedExceptionAction<ListLabelsResponse> action =
205 new PrivilegedExceptionAction<ListLabelsResponse>() {
206 public ListLabelsResponse run() throws Exception {
207 ListLabelsResponse response = null;
208 try {
209 response = VisibilityClient.listLabels(conf, ".*secret");
210 } catch (Throwable e) {
211 fail("Should not have thrown exception");
212 }
213
214 List<ByteString> labels = response.getLabelList();
215 assertEquals(2, labels.size());
216 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
217 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
218 return null;
219 }
220 };
221 SUPERUSER.runAs(action);
222 }
223
224 @Test(timeout = 60 * 1000)
225 public void testVisibilityLabelsOnWALReplay() throws Exception {
226 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
227 HTable table = null;
228 try {
229 table = createTableAndWriteDataWithLabels(tableName,
230 "(" + SECRET + "|" + CONFIDENTIAL + ")", PRIVATE);
231 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
232 .getRegionServerThreads();
233 for (RegionServerThread rsThread : regionServerThreads) {
234 rsThread.getRegionServer().abort("Aborting ");
235 }
236
237 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
238 waitForLabelsRegionAvailability(rs.getRegionServer());
239 Scan s = new Scan();
240 s.setAuthorizations(new Authorizations(SECRET));
241 ResultScanner scanner = table.getScanner(s);
242 Result[] next = scanner.next(3);
243 assertTrue(next.length == 1);
244 } finally {
245 table.close();
246 }
247 }
248 }