Repository: incubator-ranger
Updated Branches:
  refs/heads/master e0d240246 -> 0a160d601


RANGER-1180 - Add HBase Authorization tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/0a160d60
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/0a160d60
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/0a160d60

Branch: refs/heads/master
Commit: 0a160d601c9004697a49c2f2bbcfc1d4382d1c6a
Parents: e0d2402
Author: Colm O hEigeartaigh <cohei...@apache.org>
Authored: Thu Oct 13 15:43:40 2016 +0100
Committer: Colm O hEigeartaigh <cohei...@apache.org>
Committed: Thu Oct 13 15:43:40 2016 +0100

----------------------------------------------------------------------
 hbase-agent/pom.xml                             |  51 ++
 .../hbase/HBaseRangerAuthorizationTest.java     | 600 +++++++++++++++++++
 .../hbase/RangerAdminClientImpl.java            |  84 +++
 .../src/test/resources/hbase-policies.json      | 378 ++++++++++++
 .../test/resources/ranger-hbase-security.xml    |  60 ++
 5 files changed, 1173 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0a160d60/hbase-agent/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-agent/pom.xml b/hbase-agent/pom.xml
index c93e382..7fc76c1 100644
--- a/hbase-agent/pom.xml
+++ b/hbase-agent/pom.xml
@@ -74,5 +74,56 @@
                <artifactId>httpcore</artifactId>
                <version>${httpcomponents.httpcore.version}</version>
                </dependency>
+        <dependency>
+            <groupId>org.apache.hbase</groupId>
+            <artifactId>hbase-server</artifactId>
+            <version>${hbase.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hbase</groupId>
+            <artifactId>hbase-hadoop2-compat</artifactId>
+            <version>${hbase.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hbase</groupId>
+            <artifactId>hbase-hadoop-compat</artifactId>
+            <version>${hbase.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-minicluster</artifactId>
+            <version>${hadoop.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-common</artifactId>
+            <version>${hadoop.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-auth</artifactId>
+            <version>${hadoop.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
     </dependencies>
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+                <filtering>true</filtering>
+            </testResource>
+        </testResources>
+    </build>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0a160d60/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HBaseRangerAuthorizationTest.java
----------------------------------------------------------------------
diff --git 
a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HBaseRangerAuthorizationTest.java
 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HBaseRangerAuthorizationTest.java
new file mode 100644
index 0000000..8fe6284
--- /dev/null
+++ 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HBaseRangerAuthorizationTest.java
@@ -0,0 +1,600 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hbase;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.security.PrivilegedExceptionAction;
+import java.util.Arrays;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * A custom RangerAdminClient is plugged into Ranger in turn, which loads 
security policies from a local file. These policies were 
+ * generated in the Ranger Admin UI for a service called "HBaseTest":
+ * 
+ * a) The "logged in" user can do anything
+ * b) The IT group can read and write to the "temp" table, but only the 
"colfam1" column family.
+ * 
+ * Policies available from admin via:
+ * 
+ * http://localhost:6080/service/plugins/policies/download/HBASETest
+ */
+public class HBaseRangerAuthorizationTest {
+    
+    private static int port;
+    private static HBaseTestingUtility utility;
+    
+    
+    @org.junit.BeforeClass
+    public static void setup() throws Exception {
+        port = getFreePort();
+        
+        utility = new HBaseTestingUtility();
+        
utility.getConfiguration().set("test.hbase.zookeeper.property.clientPort", "" + 
port);
+        utility.getConfiguration().set("hbase.master.port", "" + 
getFreePort());
+        utility.getConfiguration().set("hbase.master.info.port", "" + 
getFreePort());
+        utility.getConfiguration().set("hbase.regionserver.port", "" + 
getFreePort());
+        utility.getConfiguration().set("hbase.regionserver.info.port", "" + 
getFreePort());
+        utility.getConfiguration().set("zookeeper.znode.parent", 
"/hbase-unsecure");
+
+        // Enable authorization
+        utility.getConfiguration().set("hbase.security.authorization", "true");
+        utility.getConfiguration().set("hbase.coprocessor.master.classes", 
+            
"org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor");
+        utility.getConfiguration().set("hbase.coprocessor.region.classes", 
+            
"org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor");
+
+        utility.startMiniCluster();
+
+        // Create a table as "admin"
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+
+        // Create a table
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Admin admin = conn.getAdmin();
+
+        // Create a table
+        if (!admin.tableExists(TableName.valueOf("temp"))) {
+            HTableDescriptor tableDescriptor = new 
HTableDescriptor(TableName.valueOf("temp"));
+
+            // Adding column families to table descriptor
+            tableDescriptor.addFamily(new HColumnDescriptor("colfam1"));
+            tableDescriptor.addFamily(new HColumnDescriptor("colfam2"));
+
+            admin.createTable(tableDescriptor);
+        }
+
+        // Add a new row
+        Put put = new Put(Bytes.toBytes("row1"));
+        put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val1"));
+        Table table = conn.getTable(TableName.valueOf("temp"));
+        table.put(put);
+        
+        put = new Put(Bytes.toBytes("row1"));
+        put.addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col1"), 
Bytes.toBytes("val2"));
+        table.put(put);
+
+        conn.close();
+    }
+    
+    @org.junit.AfterClass
+    public static void cleanup() throws Exception {
+        utility.shutdownMiniCluster();
+    }
+    
+    @Test
+    public void testReadTablesAsProcessOwner() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Admin admin = conn.getAdmin();
+
+        HTableDescriptor[] tableDescriptors = admin.listTables();
+        Assert.assertEquals(1, tableDescriptors.length);
+
+        conn.close();
+    }
+    
+    // This should fail, as the "IT" group only has read privileges, not admin 
privileges, on the table "temp"
+    @Test
+    public void testReadTablesAsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Admin admin = conn.getAdmin();
+                
+                HTableDescriptor[] tableDescriptors = admin.listTables();
+                Assert.assertEquals(0, tableDescriptors.length);
+        
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testCreateAndDropTables() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Admin admin = conn.getAdmin();
+
+        // Create a new table as process owner
+        HTableDescriptor tableDescriptor = new 
HTableDescriptor(TableName.valueOf("temp2"));
+
+        // Adding column families to table descriptor
+        tableDescriptor.addFamily(new HColumnDescriptor("colfam1"));
+        tableDescriptor.addFamily(new HColumnDescriptor("colfam2"));
+
+        admin.createTable(tableDescriptor);
+
+        conn.close();
+        
+        // Try to disable + delete the table as the "IT" group
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Admin admin = conn.getAdmin();
+                
+                try {
+                    admin.disableTable(TableName.valueOf("temp2"));
+                    admin.deleteTable(TableName.valueOf("temp2"));
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+                
+                conn.close();
+                return null;
+            }
+        });
+        
+        // Now disable and delete as process owner
+        conn = ConnectionFactory.createConnection(conf);
+        admin = conn.getAdmin();
+        admin.disableTable(TableName.valueOf("temp2"));
+        admin.deleteTable(TableName.valueOf("temp2"));
+        
+        conn.close();
+    }
+    
+    @Test
+    public void testReadRowAsProcessOwner() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Table table = conn.getTable(TableName.valueOf("temp"));
+        
+        // Read a row
+        Get get = new Get(Bytes.toBytes("row1"));
+        Result result = table.get(get);
+        byte[] valResult = result.getValue(Bytes.toBytes("colfam1"), 
Bytes.toBytes("col1"));
+        Assert.assertTrue(Arrays.equals(valResult, Bytes.toBytes("val1")));
+        
+        conn.close();
+    }
+    
+    @Test
+    public void testReadRowAsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Read a row
+                Get get = new Get(Bytes.toBytes("row1"));
+                Result result = table.get(get);
+                byte[] valResult = result.getValue(Bytes.toBytes("colfam1"), 
Bytes.toBytes("col1"));
+                Assert.assertTrue(Arrays.equals(valResult, 
Bytes.toBytes("val1")));
+
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    // This should fail as "public" doesn't have the right to read the table
+    @Test
+    public void testReadRowAsGroupPublic() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"public"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Read a row
+                try {
+                    Get get = new Get(Bytes.toBytes("row1"));
+                    table.get(get);
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testReadRowFromColFam2AsProcessOwner() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Table table = conn.getTable(TableName.valueOf("temp"));
+
+        // Read a row
+        Get get = new Get(Bytes.toBytes("row1"));
+        Result result = table.get(get);
+        byte[] valResult = result.getValue(Bytes.toBytes("colfam2"), 
Bytes.toBytes("col1"));
+        Assert.assertTrue(Arrays.equals(valResult, Bytes.toBytes("val2")));
+
+        conn.close();
+    }
+    
+    @Test
+    public void testReadRowFromColFam2AsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Read a row
+                Get get = new Get(Bytes.toBytes("row1"));
+                Result result = table.get(get);
+                byte[] valResult = result.getValue(Bytes.toBytes("colfam2"), 
Bytes.toBytes("col1"));
+                Assert.assertNull(valResult);
+
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testWriteRowAsProcessOwner() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Table table = conn.getTable(TableName.valueOf("temp"));
+        
+        // Add a new row
+        Put put = new Put(Bytes.toBytes("row2"));
+        put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val2"));
+        table.put(put);
+        
+        conn.close();
+    }
+    
+    @Test
+    public void testWriteRowAsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Add a new row
+                Put put = new Put(Bytes.toBytes("row3"));
+                put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val2"));
+                table.put(put);
+                
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testWriteRowAsGroupPublic() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"public"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Add a new row
+                try {
+                    Put put = new Put(Bytes.toBytes("row3"));
+                    put.addColumn(Bytes.toBytes("colfam1"), 
Bytes.toBytes("col1"), Bytes.toBytes("val2"));
+                    table.put(put);
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+                
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testWriteRowInColFam2AsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                // Add a new row
+                try {
+                    Put put = new Put(Bytes.toBytes("row3"));
+                    put.addColumn(Bytes.toBytes("colfam2"), 
Bytes.toBytes("col1"), Bytes.toBytes("val2"));
+                    table.put(put);
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+                
+                conn.close();
+                return null;
+            }
+        });
+    }
+    
+    @Test
+    public void testReadRowInAnotherTable() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Admin admin = conn.getAdmin();
+
+        // Create a new table as process owner
+        HTableDescriptor tableDescriptor = new 
HTableDescriptor(TableName.valueOf("temp4"));
+
+        // Adding column families to table descriptor
+        tableDescriptor.addFamily(new HColumnDescriptor("colfam1"));
+        tableDescriptor.addFamily(new HColumnDescriptor("colfam2"));
+
+        admin.createTable(tableDescriptor);
+
+        // Write a value
+        Put put = new Put(Bytes.toBytes("row1"));
+        put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val1"));
+        Table table = conn.getTable(TableName.valueOf("temp4"));
+        table.put(put);
+        
+        // Read a row
+        Get get = new Get(Bytes.toBytes("row1"));
+        Result result = table.get(get);
+        byte[] valResult = result.getValue(Bytes.toBytes("colfam2"), 
Bytes.toBytes("col1"));
+        Assert.assertNull(valResult);
+        
+        conn.close();
+        
+        // Now try to read the row as group "IT" - it should fail as "IT" can 
only read from table "temp"
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp4"));
+                
+                // Read a row
+                try {
+                    Get get = new Get(Bytes.toBytes("row1"));
+                    table.get(get);
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+
+                conn.close();
+                return null;
+            }
+        });
+        
+        // Now disable and delete as process owner
+        conn = ConnectionFactory.createConnection(conf);
+        admin = conn.getAdmin();
+        admin.disableTable(TableName.valueOf("temp4"));
+        admin.deleteTable(TableName.valueOf("temp4"));
+        
+        conn.close();
+    }
+    
+    @Test
+    public void testDeleteRowAsProcessOwner() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Table table = conn.getTable(TableName.valueOf("temp"));
+        
+        // Add a new row
+        Put put = new Put(Bytes.toBytes("row4"));
+        put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val2"));
+        table.put(put);
+        
+        // Delete the new row
+        Delete delete = new Delete(Bytes.toBytes("row4"));
+        table.delete(delete);
+        
+        conn.close();
+    }
+    
+    @Test
+    public void testDeleteRowAsGroupIT() throws Exception {
+        final Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "localhost");
+        conf.set("hbase.zookeeper.property.clientPort", "" + port);
+        conf.set("zookeeper.znode.parent", "/hbase-unsecure");
+        
+        Connection conn = ConnectionFactory.createConnection(conf);
+        Table table = conn.getTable(TableName.valueOf("temp"));
+        
+        // Add a new row (as process owner)
+        Put put = new Put(Bytes.toBytes("row5"));
+        put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col1"), 
Bytes.toBytes("val2"));
+        table.put(put);
+        
+        String user = "bob";
+        if ("bob".equals(System.getProperty("user.name"))) {
+            user = "alice";
+        }
+        UserGroupInformation ugi = 
UserGroupInformation.createUserForTesting(user, new String[] {"IT"});
+        ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws Exception {
+                Connection conn = ConnectionFactory.createConnection(conf);
+                Table table = conn.getTable(TableName.valueOf("temp"));
+                
+                try {
+                    // Delete the new row
+                    Delete delete = new Delete(Bytes.toBytes("row5"));
+                    table.delete(delete);
+                    Assert.fail("Failure expected on an unauthorized user");
+                } catch (IOException ex) {
+                    // expected
+                }
+                
+                conn.close();
+                return null;
+            }
+        });
+        
+        // Delete the new row (as process owner)
+        Delete delete = new Delete(Bytes.toBytes("row5"));
+        table.delete(delete);
+        
+        conn.close();
+    }
+    
+    private static int getFreePort() throws IOException {
+        ServerSocket serverSocket = new ServerSocket(0);
+        int port = serverSocket.getLocalPort();
+        serverSocket.close();
+        return port;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0a160d60/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAdminClientImpl.java
----------------------------------------------------------------------
diff --git 
a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAdminClientImpl.java
 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAdminClientImpl.java
new file mode 100644
index 0000000..3269fbb
--- /dev/null
+++ 
b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAdminClientImpl.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hbase;
+
+import java.io.File;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.util.List;
+
+import org.apache.ranger.admin.client.RangerAdminClient;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.apache.ranger.plugin.util.ServiceTags;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * A test implementation of the RangerAdminClient interface that just reads 
policies in from a file and returns them
+ */
+public class RangerAdminClientImpl implements RangerAdminClient {
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerAdminClientImpl.class);
+    private final static String cacheFilename = "hbase-policies.json";
+    private Gson gson;
+
+    public void init(String serviceName, String appId, String 
configPropertyPrefix) {
+        Gson gson = null;
+        try {
+            gson = new 
GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").setPrettyPrinting().create();
+        } catch(Throwable excp) {
+            LOG.error("RangerAdminClientImpl: failed to create GsonBuilder 
object", excp);
+        }
+        this.gson = gson;
+    }
+
+    public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion) 
throws Exception {
+
+        String basedir = System.getProperty("basedir");
+        if (basedir == null) {
+            basedir = new File(".").getCanonicalPath();
+        }
+
+        java.nio.file.Path cachePath = 
FileSystems.getDefault().getPath(basedir, "/target/test-classes/" + 
cacheFilename);
+        byte[] cacheBytes = Files.readAllBytes(cachePath);
+
+        return gson.fromJson(new String(cacheBytes), ServicePolicies.class);
+    }
+
+    public void grantAccess(GrantRevokeRequest request) throws Exception {
+        
+    }
+
+    public void revokeAccess(GrantRevokeRequest request) throws Exception {
+        
+    }
+
+    public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion) throws 
Exception {
+        return null;
+        
+    }
+
+    public List<String> getTagTypes(String tagTypePattern) throws Exception {
+        return null;
+    }
+
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0a160d60/hbase-agent/src/test/resources/hbase-policies.json
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/resources/hbase-policies.json 
b/hbase-agent/src/test/resources/hbase-policies.json
new file mode 100644
index 0000000..30088c6
--- /dev/null
+++ b/hbase-agent/src/test/resources/hbase-policies.json
@@ -0,0 +1,378 @@
+{
+  "serviceName": "HBASETest",
+  "serviceId": 8,
+  "policyVersion": 26,
+  "policyUpdateTime": "20160622-11:01:03.000-+0100",
+  "policies": [
+    {
+      "service": "HBASETest",
+      "name": "HBASETest-1-20160620102221",
+      "description": "Default Policy for Service: HBASETest",
+      "resourceSignature": "e1b3b654519228996d282db63d795c7e",
+      "isAuditEnabled": true,
+      "resources": {
+        "column": {
+          "values": [
+            "*"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        },
+        "column-family": {
+          "values": [
+            "*"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        },
+        "table": {
+          "values": [
+            "*"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        }
+      },
+      "policyItems": [
+        {
+          "accesses": [
+            {
+              "type": "read",
+              "isAllowed": true
+            },
+            {
+              "type": "write",
+              "isAllowed": true
+            },
+            {
+              "type": "create",
+              "isAllowed": true
+            },
+            {
+              "type": "admin",
+              "isAllowed": true
+            }
+          ],
+          "users": [
+            "${user.name}"
+          ],
+          "groups": [
+            "supergroup"
+          ],
+          "conditions": [],
+          "delegateAdmin": true
+        }
+      ],
+      "denyPolicyItems": [],
+      "allowExceptions": [],
+      "denyExceptions": [],
+      "dataMaskPolicyItems": [],
+      "rowFilterPolicyItems": [],
+      "id": 36,
+      "guid": "1466418141682_157_1833",
+      "isEnabled": true,
+      "createdBy": "Admin",
+      "updatedBy": "Admin",
+      "createTime": "20160620-11:22:21.000-+0100",
+      "updateTime": "20160621-12:32:00.000-+0100",
+      "version": 14
+    },
+    {
+      "service": "HBASETest",
+      "name": "ReadWriteTempColFam1",
+      "description": "",
+      "resourceSignature": "6ae42ce98505037fdaca33f6d6818cb4",
+      "isAuditEnabled": true,
+      "resources": {
+        "column": {
+          "values": [
+            "*"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        },
+        "column-family": {
+          "values": [
+            "colfam1"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        },
+        "table": {
+          "values": [
+            "temp"
+          ],
+          "isExcludes": false,
+          "isRecursive": false
+        }
+      },
+      "policyItems": [
+        {
+          "accesses": [
+            {
+              "type": "read",
+              "isAllowed": true
+            },
+            {
+              "type": "write",
+              "isAllowed": true
+            }
+          ],
+          "users": [],
+          "groups": [
+            "IT"
+          ],
+          "conditions": [],
+          "delegateAdmin": false
+        }
+      ],
+      "denyPolicyItems": [],
+      "allowExceptions": [],
+      "denyExceptions": [],
+      "dataMaskPolicyItems": [],
+      "rowFilterPolicyItems": [],
+      "id": 37,
+      "guid": "1466509013694_902_2140",
+      "isEnabled": true,
+      "createdBy": "Admin",
+      "updatedBy": "Admin",
+      "createTime": "20160621-12:36:53.000-+0100",
+      "updateTime": "20160622-11:01:02.000-+0100",
+      "version": 19
+    }
+  ],
+  "serviceDef": {
+    "name": "hbase",
+    "implClass": "org.apache.ranger.services.hbase.RangerServiceHBase",
+    "label": "HBase",
+    "description": "HBase",
+    "options": {},
+    "configs": [
+      {
+        "itemId": 1,
+        "name": "username",
+        "type": "string",
+        "subType": "",
+        "mandatory": true,
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "Username"
+      },
+      {
+        "itemId": 2,
+        "name": "password",
+        "type": "password",
+        "subType": "",
+        "mandatory": true,
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "Password"
+      },
+      {
+        "itemId": 3,
+        "name": "hadoop.security.authentication",
+        "type": "enum",
+        "subType": "authnType",
+        "mandatory": true,
+        "defaultValue": "simple",
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": ""
+      },
+      {
+        "itemId": 4,
+        "name": "hbase.master.kerberos.principal",
+        "type": "string",
+        "subType": "",
+        "mandatory": false,
+        "defaultValue": ""
+      },
+      {
+        "itemId": 5,
+        "name": "hbase.security.authentication",
+        "type": "enum",
+        "subType": "authnType",
+        "mandatory": true,
+        "defaultValue": "simple",
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": ""
+      },
+      {
+        "itemId": 6,
+        "name": "hbase.zookeeper.property.clientPort",
+        "type": "int",
+        "subType": "",
+        "mandatory": true,
+        "defaultValue": "2181",
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": ""
+      },
+      {
+        "itemId": 7,
+        "name": "hbase.zookeeper.quorum",
+        "type": "string",
+        "subType": "",
+        "mandatory": true,
+        "defaultValue": "",
+        "validationRegEx": "",
+        "validationMessage": ""
+      },
+      {
+        "itemId": 8,
+        "name": "zookeeper.znode.parent",
+        "type": "string",
+        "subType": "",
+        "mandatory": true,
+        "defaultValue": "/hbase",
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": ""
+      },
+      {
+        "itemId": 9,
+        "name": "commonNameForCertificate",
+        "type": "string",
+        "subType": "",
+        "mandatory": false,
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "Common Name for Certificate"
+      }
+    ],
+    "resources": [
+      {
+        "itemId": 1,
+        "name": "table",
+        "type": "string",
+        "level": 10,
+        "mandatory": true,
+        "lookupSupported": true,
+        "recursiveSupported": false,
+        "excludesSupported": true,
+        "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": "true",
+          "ignoreCase": "false"
+        },
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "HBase Table",
+        "description": "HBase Table"
+      },
+      {
+        "itemId": 2,
+        "name": "column-family",
+        "type": "string",
+        "level": 20,
+        "parent": "table",
+        "mandatory": true,
+        "lookupSupported": true,
+        "recursiveSupported": false,
+        "excludesSupported": true,
+        "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": "true",
+          "ignoreCase": "false"
+        },
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "HBase Column-family",
+        "description": "HBase Column-family"
+      },
+      {
+        "itemId": 3,
+        "name": "column",
+        "type": "string",
+        "level": 30,
+        "parent": "column-family",
+        "mandatory": true,
+        "lookupSupported": true,
+        "recursiveSupported": false,
+        "excludesSupported": true,
+        "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": "true",
+          "ignoreCase": "false"
+        },
+        "validationRegEx": "",
+        "validationMessage": "",
+        "uiHint": "",
+        "label": "HBase Column",
+        "description": "HBase Column"
+      }
+    ],
+    "accessTypes": [
+      {
+        "itemId": 1,
+        "name": "read",
+        "label": "Read",
+        "impliedGrants": []
+      },
+      {
+        "itemId": 2,
+        "name": "write",
+        "label": "Write",
+        "impliedGrants": []
+      },
+      {
+        "itemId": 3,
+        "name": "create",
+        "label": "Create",
+        "impliedGrants": []
+      },
+      {
+        "itemId": 4,
+        "name": "admin",
+        "label": "Admin",
+        "impliedGrants": [
+          "read",
+          "write",
+          "create"
+        ]
+      }
+    ],
+    "policyConditions": [],
+    "contextEnrichers": [],
+    "enums": [
+      {
+        "itemId": 1,
+        "name": "authnType",
+        "elements": [
+          {
+            "itemId": 1,
+            "name": "simple",
+            "label": "Simple"
+          },
+          {
+            "itemId": 2,
+            "name": "kerberos",
+            "label": "Kerberos"
+          }
+        ],
+        "defaultIndex": 0
+      }
+    ],
+    "dataMaskDef": {
+      "maskTypes": [],
+      "accessTypes": [],
+      "resources": []
+    },
+    "rowFilterDef": {
+      "accessTypes": [],
+      "resources": []
+    },
+    "id": 2,
+    "guid": "d6cea1f0-2509-4791-8fc1-7b092399ba3b",
+    "isEnabled": true,
+    "createTime": "20160314-14:39:35.000-+0000",
+    "updateTime": "20160314-14:39:35.000-+0000",
+    "version": 1
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0a160d60/hbase-agent/src/test/resources/ranger-hbase-security.xml
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/resources/ranger-hbase-security.xml 
b/hbase-agent/src/test/resources/ranger-hbase-security.xml
new file mode 100644
index 0000000..b71f18c
--- /dev/null
+++ b/hbase-agent/src/test/resources/ranger-hbase-security.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude";>
+       <property>
+               <name>ranger.plugin.hbase.policy.rest.url</name>
+               <value>http://localhost:6080</value>
+               <description>
+                       URL to Ranger Admin
+               </description>
+       </property>
+
+       <property>
+               <name>ranger.plugin.hbase.service.name</name>
+               <value>HBASETest</value>
+               <description>
+                       Name of the Ranger service containing policies for this 
SampleApp instance
+               </description>
+       </property>
+
+       <property>
+        <name>ranger.plugin.hbase.policy.source.impl</name>
+        
<value>org.apache.ranger.authorization.hbase.RangerAdminClientImpl</value>
+        <description>
+            Policy source.
+        </description>
+    </property>
+    
+       <property>
+               <name>ranger.plugin.hbase.policy.pollIntervalMs</name>
+               <value>30000</value>
+               <description>
+                       How often to poll for changes in policies?
+               </description>
+       </property>
+
+       <property>
+               <name>ranger.plugin.hbase.policy.cache.dir</name>
+               <value>${project.build.directory}</value>
+               <description>
+                       Directory where Ranger policies are cached after 
successful retrieval from the source
+               </description>
+       </property>
+
+</configuration>


Reply via email to