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.apache.hadoop.hbase.AuthUtil.toGroupEntry;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.util.List;
25
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.HBaseTestingUtility;
28 import org.apache.hadoop.hbase.HColumnDescriptor;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.HTableDescriptor;
31 import org.apache.hadoop.hbase.NamespaceDescriptor;
32 import org.apache.hadoop.hbase.client.HTable;
33 import org.apache.hadoop.hbase.testclassification.MediumTests;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.Get;
36 import org.apache.hadoop.hbase.client.Result;
37 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
38 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
39 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
40 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
41 import org.apache.hadoop.hbase.security.User;
42 import org.apache.hadoop.hbase.security.access.Permission.Action;
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 import com.google.common.collect.ListMultimap;
50 import com.google.protobuf.BlockingRpcChannel;
51
52 @Category(MediumTests.class)
53 public class TestNamespaceCommands extends SecureTestUtil {
54 private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
55 private static String TEST_NAMESPACE = "ns1";
56 private static String TEST_NAMESPACE2 = "ns2";
57 private static Configuration conf;
58 private static MasterCoprocessorEnvironment CP_ENV;
59 private static AccessController ACCESS_CONTROLLER;
60
61
62 private static User SUPERUSER;
63
64 private static User USER_RW;
65
66 private static User USER_CREATE;
67
68 private static User USER_NSP_WRITE;
69
70 private static User USER_NSP_ADMIN;
71
72 private static final String GROUP_ADMIN = "group_admin";
73 private static final String GROUP_CREATE = "group_create";
74 private static final String GROUP_READ = "group_read";
75 private static final String GROUP_WRITE = "group_write";
76
77 private static User USER_GROUP_ADMIN;
78 private static User USER_GROUP_CREATE;
79 private static User USER_GROUP_READ;
80 private static User USER_GROUP_WRITE;
81
82 private static String TEST_TABLE = TEST_NAMESPACE + ":testtable";
83 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
84
85 @BeforeClass
86 public static void beforeClass() throws Exception {
87 conf = UTIL.getConfiguration();
88 enableSecurity(conf);
89
90 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
91 USER_RW = User.createUserForTesting(conf, "rw_user", new String[0]);
92 USER_CREATE = User.createUserForTesting(conf, "create_user", new String[0]);
93 USER_NSP_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
94 USER_NSP_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
95
96 USER_GROUP_ADMIN =
97 User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
98 USER_GROUP_CREATE =
99 User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
100 USER_GROUP_READ =
101 User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
102 USER_GROUP_WRITE =
103 User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
104
105 UTIL.startMiniCluster();
106
107 UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME.getName(), 30 * 1000);
108
109 ACCESS_CONTROLLER = (AccessController) UTIL.getMiniHBaseCluster().getMaster()
110 .getCoprocessorHost()
111 .findCoprocessor(AccessController.class.getName());
112
113 UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build());
114 UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build());
115
116 grantOnNamespace(UTIL, USER_NSP_WRITE.getShortName(),
117 TEST_NAMESPACE, Permission.Action.WRITE, Permission.Action.CREATE);
118
119 grantOnNamespace(UTIL, USER_NSP_ADMIN.getShortName(), TEST_NAMESPACE, Permission.Action.ADMIN);
120 grantOnNamespace(UTIL, USER_NSP_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN);
121
122 grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
123 grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
124 grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
125 grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
126 }
127
128 @AfterClass
129 public static void afterClass() throws Exception {
130 UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE);
131 UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE2);
132 UTIL.shutdownMiniCluster();
133 }
134
135 @Test
136 public void testAclTableEntries() throws Exception {
137 String userTestNamespace = "userTestNsp";
138 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
139 try {
140
141 grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
142 Permission.Action.WRITE);
143
144 Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
145 assertTrue(result != null);
146 ListMultimap<String, TablePermission> perms =
147 AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
148 assertEquals(3, perms.size());
149 List<TablePermission> namespacePerms = perms.get(userTestNamespace);
150 assertTrue(perms.containsKey(userTestNamespace));
151 assertEquals(1, namespacePerms.size());
152 assertEquals(TEST_NAMESPACE,
153 namespacePerms.get(0).getNamespace());
154 assertEquals(null, namespacePerms.get(0).getFamily());
155 assertEquals(null, namespacePerms.get(0).getQualifier());
156 assertEquals(1, namespacePerms.get(0).getActions().length);
157 assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getActions()[0]);
158
159
160 revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
161 Permission.Action.WRITE);
162
163 perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
164 assertEquals(2, perms.size());
165 } finally {
166 acl.close();
167 }
168 }
169
170 @Test
171 public void testModifyNamespace() throws Exception {
172 AccessTestAction modifyNamespace = new AccessTestAction() {
173 public Object run() throws Exception {
174 ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
175 NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
176 return null;
177 }
178 };
179
180 verifyAllowed(modifyNamespace, SUPERUSER, USER_NSP_ADMIN, USER_GROUP_ADMIN);
181
182 verifyDenied(modifyNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW, USER_GROUP_READ,
183 USER_GROUP_WRITE, USER_GROUP_CREATE);
184 }
185
186 @Test
187 public void testCreateAndDeleteNamespace() throws Exception {
188 AccessTestAction createNamespace = new AccessTestAction() {
189 public Object run() throws Exception {
190 ACCESS_CONTROLLER.preCreateNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
191 NamespaceDescriptor.create(TEST_NAMESPACE2).build());
192 return null;
193 }
194 };
195
196 AccessTestAction deleteNamespace = new AccessTestAction() {
197 public Object run() throws Exception {
198 ACCESS_CONTROLLER.preDeleteNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
199 TEST_NAMESPACE2);
200 return null;
201 }
202 };
203
204
205 verifyAllowed(createNamespace, SUPERUSER, USER_GROUP_ADMIN);
206
207 verifyAllowed(deleteNamespace, SUPERUSER, USER_NSP_ADMIN, USER_GROUP_ADMIN);
208
209
210 verifyDenied(createNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW, USER_NSP_ADMIN,
211 USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
212 verifyDenied(deleteNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW, USER_GROUP_READ,
213 USER_GROUP_WRITE, USER_GROUP_CREATE);
214 }
215
216 @Test
217 public void testGrantRevoke() throws Exception{
218 final String testUser = "testUser";
219
220
221
222 AccessTestAction grantAction = new AccessTestAction() {
223 public Object run() throws Exception {
224 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
225 try {
226 BlockingRpcChannel service =
227 acl.coprocessorService(HConstants.EMPTY_START_ROW);
228 AccessControlService.BlockingInterface protocol =
229 AccessControlService.newBlockingStub(service);
230 ProtobufUtil.grant(protocol, testUser, TEST_NAMESPACE, Action.WRITE);
231 } finally {
232 acl.close();
233 }
234 return null;
235 }
236 };
237
238 AccessTestAction revokeAction = new AccessTestAction() {
239 public Object run() throws Exception {
240 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
241 try {
242 BlockingRpcChannel service =
243 acl.coprocessorService(HConstants.EMPTY_START_ROW);
244 AccessControlService.BlockingInterface protocol =
245 AccessControlService.newBlockingStub(service);
246 ProtobufUtil.revoke(protocol, testUser, TEST_NAMESPACE, Action.WRITE);
247 } finally {
248 acl.close();
249 }
250 return null;
251 }
252 };
253
254 AccessTestAction getPermissionsAction = new AccessTestAction() {
255 @Override
256 public Object run() throws Exception {
257 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
258 try {
259 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
260 AccessControlService.BlockingInterface protocol =
261 AccessControlService.newBlockingStub(service);
262 ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(TEST_NAMESPACE));
263 } finally {
264 acl.close();
265 }
266 return null;
267 }
268 };
269
270
271
272 verifyAllowed(grantAction, SUPERUSER, USER_NSP_ADMIN, USER_GROUP_ADMIN);
273 verifyDenied(grantAction, USER_CREATE, USER_RW, USER_GROUP_READ, USER_GROUP_WRITE,
274 USER_GROUP_CREATE);
275 verifyAllowed(revokeAction, SUPERUSER, USER_NSP_ADMIN, USER_GROUP_ADMIN);
276 verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_GROUP_READ, USER_GROUP_WRITE,
277 USER_GROUP_CREATE);
278
279
280 verifyAllowed(revokeAction, SUPERUSER, USER_NSP_ADMIN, USER_GROUP_ADMIN);
281 verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_GROUP_READ, USER_GROUP_WRITE,
282 USER_GROUP_CREATE);
283 }
284
285 @Test
286 public void testCreateTableWithNamespace() throws Exception {
287 AccessTestAction createTable = new AccessTestAction() {
288 @Override
289 public Object run() throws Exception {
290 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
291 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
292 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
293 return null;
294 }
295 };
296
297
298 verifyAllowed(createTable, SUPERUSER, USER_NSP_WRITE, USER_GROUP_CREATE);
299
300
301 verifyDenied(createTable, USER_CREATE, USER_RW, USER_GROUP_READ, USER_GROUP_WRITE,
302 USER_GROUP_ADMIN);
303 }
304 }