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