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 com.google.common.collect.ListMultimap;
26 import com.google.protobuf.BlockingRpcChannel;
27
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.HTableDescriptor;
33 import org.apache.hadoop.hbase.NamespaceDescriptor;
34 import org.apache.hadoop.hbase.MediumTests;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.client.Get;
37 import org.apache.hadoop.hbase.client.HTable;
38 import org.apache.hadoop.hbase.client.Result;
39 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
40 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
41 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
42 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
43 import org.apache.hadoop.hbase.security.User;
44 import org.apache.hadoop.hbase.security.access.Permission.Action;
45 import org.apache.hadoop.hbase.util.Bytes;
46 import org.junit.AfterClass;
47 import org.junit.BeforeClass;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50
51 import java.util.List;
52
53 import static org.junit.Assert.assertEquals;
54 import static org.junit.Assert.assertTrue;
55
56 @Category(MediumTests.class)
57 public class TestNamespaceCommands extends SecureTestUtil {
58 private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
59 private static String TestNamespace = "ns1";
60 private static Configuration conf;
61 private static MasterCoprocessorEnvironment CP_ENV;
62 private static AccessController ACCESS_CONTROLLER;
63
64
65 private static User SUPERUSER;
66
67 private static User USER_RW;
68
69 private static User USER_CREATE;
70
71 private static User USER_NSP_WRITE;
72
73 private static String TEST_TABLE = TestNamespace + ":testtable";
74 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
75
76 @BeforeClass
77 public static void beforeClass() throws Exception {
78 conf = UTIL.getConfiguration();
79 enableSecurity(conf);
80
81 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
82 USER_RW = User.createUserForTesting(conf, "rw_user", new String[0]);
83 USER_CREATE = User.createUserForTesting(conf, "create_user", new String[0]);
84 USER_NSP_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
85
86 UTIL.startMiniCluster();
87
88 UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME.getName(), 30 * 1000);
89
90 ACCESS_CONTROLLER = (AccessController) UTIL.getMiniHBaseCluster().getMaster()
91 .getCoprocessorHost()
92 .findCoprocessor(AccessController.class.getName());
93
94 UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TestNamespace).build());
95
96 grantOnNamespace(UTIL, USER_NSP_WRITE.getShortName(),
97 TestNamespace, Permission.Action.WRITE, Permission.Action.CREATE);
98 }
99
100 @AfterClass
101 public static void afterClass() throws Exception {
102 UTIL.getHBaseAdmin().deleteNamespace(TestNamespace);
103 UTIL.shutdownMiniCluster();
104 }
105
106 @Test
107 public void testAclTableEntries() throws Exception {
108 String userTestNamespace = "userTestNsp";
109 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
110 try {
111
112 grantOnNamespace(UTIL, userTestNamespace, TestNamespace,
113 Permission.Action.WRITE);
114
115 Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
116 assertTrue(result != null);
117 ListMultimap<String, TablePermission> perms =
118 AccessControlLists.getNamespacePermissions(conf, TestNamespace);
119 assertEquals(2, perms.size());
120 List<TablePermission> namespacePerms = perms.get(userTestNamespace);
121 assertTrue(perms.containsKey(userTestNamespace));
122 assertEquals(1, namespacePerms.size());
123 assertEquals(TestNamespace,
124 namespacePerms.get(0).getNamespace());
125 assertEquals(null, namespacePerms.get(0).getFamily());
126 assertEquals(null, namespacePerms.get(0).getQualifier());
127 assertEquals(1, namespacePerms.get(0).getActions().length);
128 assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getActions()[0]);
129
130
131 revokeFromNamespace(UTIL, userTestNamespace, TestNamespace,
132 Permission.Action.WRITE);
133
134 perms = AccessControlLists.getNamespacePermissions(conf, TestNamespace);
135 assertEquals(1, perms.size());
136 } finally {
137 acl.close();
138 }
139 }
140
141 @Test
142 public void testModifyNamespace() throws Exception {
143 AccessTestAction modifyNamespace = new AccessTestAction() {
144 public Object run() throws Exception {
145 ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
146 NamespaceDescriptor.create(TestNamespace).addConfiguration("abc", "156").build());
147 return null;
148 }
149 };
150
151 verifyAllowed(modifyNamespace, SUPERUSER);
152
153 verifyDenied(modifyNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW);
154 }
155
156 @Test
157 public void testGrantRevoke() throws Exception{
158 final String testUser = "testUser";
159
160
161
162 AccessTestAction grantAction = new AccessTestAction() {
163 public Object run() throws Exception {
164 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
165 try {
166 BlockingRpcChannel service =
167 acl.coprocessorService(HConstants.EMPTY_START_ROW);
168 AccessControlService.BlockingInterface protocol =
169 AccessControlService.newBlockingStub(service);
170 ProtobufUtil.grant(protocol, testUser, TestNamespace, Action.WRITE);
171 } finally {
172 acl.close();
173 }
174 return null;
175 }
176 };
177
178 AccessTestAction revokeAction = new AccessTestAction() {
179 public Object run() throws Exception {
180 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
181 try {
182 BlockingRpcChannel service =
183 acl.coprocessorService(HConstants.EMPTY_START_ROW);
184 AccessControlService.BlockingInterface protocol =
185 AccessControlService.newBlockingStub(service);
186 ProtobufUtil.revoke(protocol, testUser, TestNamespace, Action.WRITE);
187 } finally {
188 acl.close();
189 }
190 return null;
191 }
192 };
193
194
195
196 verifyAllowed(grantAction, SUPERUSER);
197 verifyDenied(grantAction, USER_CREATE, USER_RW);
198 verifyAllowed(revokeAction, SUPERUSER);
199 verifyDenied(revokeAction, USER_CREATE, USER_RW);
200 }
201
202 @Test
203 public void testCreateTableWithNamespace() throws Exception {
204 AccessTestAction createTable = new AccessTestAction() {
205 @Override
206 public Object run() throws Exception {
207 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
208 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
209 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
210 return null;
211 }
212 };
213
214
215 verifyAllowed(createTable, SUPERUSER, USER_NSP_WRITE);
216
217
218 verifyDenied(createTable, USER_CREATE, USER_RW);
219 }
220 }