Coverage Summary for Class: TestReadOnlyRole (org.umlg.sqlg.test.roles)

Class Method, % Branch, % Line, %
TestReadOnlyRole 100% (5/5) 28.6% (4/14) 94.1% (48/51)
TestReadOnlyRole$1 100% (1/1) 100% (1/1)
TestReadOnlyRole$TopologyGrantListener 100% (2/2) 24.5% (12/49) 41.8% (28/67)
Total 100% (8/8) 25.4% (16/63) 64.7% (77/119)


 package org.umlg.sqlg.test.roles;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.builder.fluent.Configurations;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.umlg.sqlg.structure.SqlgGraph;
 import org.umlg.sqlg.structure.TopologyChangeAction;
 import org.umlg.sqlg.structure.TopologyInf;
 import org.umlg.sqlg.structure.TopologyListener;
 import org.umlg.sqlg.structure.topology.EdgeLabel;
 import org.umlg.sqlg.structure.topology.Schema;
 import org.umlg.sqlg.structure.topology.Topology;
 import org.umlg.sqlg.structure.topology.VertexLabel;
 import org.umlg.sqlg.test.BaseTest;
 
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.List;
 
 /**
  * @author <a href="https://github.com/pietermartin">Pieter Martin</a>
  * Date: 2018/07/21
  */
 public class TestReadOnlyRole extends BaseTest {
 
     @Before
     public void before() throws Exception {
         //H2 is locking on opening readOnly connection.
         //TODO remove hsqldb depending on https://github.com/pietermartin/sqlg/issues/411
         Assume.assumeFalse(isH2() || isHsqldb());
         super.before();
     }
 
     @Test
     public void testReadOnlyRoleOnPublicTable() throws ConfigurationException {
         TopologyGrantListener topologyGrantListener = new TopologyGrantListener();
         this.sqlgGraph.getTopology().registerListener(topologyGrantListener);
 
         this.sqlgGraph.addVertex(T.label, "A", "name", "a1");
         this.sqlgGraph.addVertex(T.label, "A", "name", "a2");
         this.sqlgGraph.tx().commit();
 
         Configurations configs = new Configurations();
         Configuration readOnlyConfiguration = configs.properties("sqlg.readonly.properties");
         try (SqlgGraph readOnlyGraph = SqlgGraph.open(readOnlyConfiguration)) {
             List<Vertex> vertices = readOnlyGraph.traversal().V().hasLabel("A").toList();
             Assert.assertEquals(2, vertices.size());
             try {
                 readOnlyGraph.addVertex(T.label, "A", "name", "a3");
                 Assert.fail("Graph is suppose to be readOnly");
             } catch (Exception ignore) {
             }
         }
     }
 
     @Test
     public void testReadOnlyRoleOnSchema() throws ConfigurationException {
         TopologyGrantListener topologyGrantListener = new TopologyGrantListener();
         this.sqlgGraph.getTopology().registerListener(topologyGrantListener);
 
         this.sqlgGraph.addVertex(T.label, "A.A", "name", "a1");
         this.sqlgGraph.addVertex(T.label, "A.A", "name", "a2");
         this.sqlgGraph.tx().commit();
 
         Configurations configs = new Configurations();
         Configuration readOnlyConfiguration = configs.properties("sqlg.readonly.properties");
         try (SqlgGraph readOnlyGraph = SqlgGraph.open(readOnlyConfiguration)) {
             List<Vertex> vertices = readOnlyGraph.traversal().V().hasLabel("A.A").toList();
             Assert.assertEquals(2, vertices.size());
             try {
                 readOnlyGraph.addVertex(T.label, "A.A", "name", "a3");
                 Assert.fail("Graph is suppose to be readOnly");
             } catch (Exception ignore) {
             }
         }
     }
 
     @Test
     public void testReadOnlyRoleOnSchemasVertexLabelAndEdgeLabel() throws ConfigurationException {
         TopologyGrantListener topologyGrantListener = new TopologyGrantListener();
         this.sqlgGraph.getTopology().registerListener(topologyGrantListener);
 
         Vertex a = this.sqlgGraph.addVertex(T.label, "A.A", "name", "a1");
         Vertex b = this.sqlgGraph.addVertex(T.label, "B.B", "name", "b1");
         a.addEdge("ab", b, "name", "ab1");
         a.addEdge("ab", b, "name", "ab1");
         this.sqlgGraph.tx().commit();
 
         Configurations configs = new Configurations();
         Configuration readOnlyConfiguration = configs.properties("sqlg.readonly.properties");
         try (SqlgGraph readOnlyGraph = SqlgGraph.open(readOnlyConfiguration)) {
             List<Edge> edges = readOnlyGraph.traversal().V().hasLabel("A.A").outE("ab").toList();
             Assert.assertEquals(2, edges.size());
             List<Vertex> vertices = readOnlyGraph.traversal().V().hasLabel("A.A").out("ab").toList();
             Assert.assertEquals(2, vertices.size());
             try {
                 Vertex vertexA = readOnlyGraph.traversal().V().hasLabel("A.A").has("name", "a1").next();
                 Vertex vertexB = readOnlyGraph.traversal().V().hasLabel("B.B").has("name", "b1").next();
                 vertexA.addEdge("ab", vertexB, "name", "ab2");
                 Assert.fail("Graph is suppose to be readOnly");
             } catch (Exception ignore) {
             }
         }
     }
 
     public class TopologyGrantListener implements TopologyListener {
 
         TopologyGrantListener() {
         }
 
         @SuppressWarnings("StatementWithEmptyBody")
         @Override
         public void change(TopologyInf topologyInf, TopologyInf oldValue, TopologyChangeAction action, boolean beforeCommit) {
             switch (action) {
                 case CREATE:
                     if (topologyInf instanceof VertexLabel vertexLabel) {
                         Connection conn = sqlgGraph.tx().getConnection();
                         try (Statement statement = conn.createStatement()) {
                             String sql;
                             if (isPostgres()) {
                                  sql = "GRANT SELECT ON " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(vertexLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.VERTEX_PREFIX + vertexLabel.getName()) + " TO \"sqlgReadOnly\"";
                                 statement.execute(sql);
                             } else if (isHsqldb()) {
                                 sql = "GRANT SELECT ON TABLE " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(vertexLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.VERTEX_PREFIX + vertexLabel.getName()) + " TO READ_ONLY";
                                 statement.execute(sql);
                             } else if (isMariaDb() || isMysql()) {
                                 //nothing to do. MariaDb user is created with select all rights
                             } else if (isMsSqlServer()) {
                                 sql = "GRANT SELECT ON OBJECT:: " +
                                         vertexLabel.getSchema().getName() + "." +
                                         Topology.VERTEX_PREFIX + vertexLabel.getName() + " TO sqlgReadOnly;";
                                 statement.execute(sql);
                             } else if (isH2()) {
                                 sql = "GRANT SELECT ON " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(vertexLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.VERTEX_PREFIX + vertexLabel.getName()) + " TO READ_ONLY";
                                 statement.execute(sql);
                             } else {
                                 Assert.fail("Not handled");
                             }
                         } catch (SQLException e) {
                             throw new RuntimeException(e);
                         }
                     } else if (topologyInf instanceof EdgeLabel edgeLabel) {
                         Connection conn = sqlgGraph.tx().getConnection();
                         try (Statement statement = conn.createStatement()) {
                             String sql;
                             if (isPostgres()) {
                                 sql = "GRANT SELECT ON " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(edgeLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.EDGE_PREFIX + edgeLabel.getName()) + " TO \"sqlgReadOnly\"";
                                 statement.execute(sql);
                             } else if (isHsqldb()) {
                                 sql = "GRANT SELECT ON TABLE " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(edgeLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.EDGE_PREFIX + edgeLabel.getName()) + " TO READ_ONLY";
                                 statement.execute(sql);
                             } else if (isMariaDb() || isMysql()) {
                                 //nothing to do. MariaDb user is created with select all rights
                             } else if (isMsSqlServer()) {
                                 sql = "GRANT SELECT ON OBJECT::" +
                                         edgeLabel.getSchema().getName() + "." +
                                         Topology.EDGE_PREFIX + edgeLabel.getName() + " TO sqlgReadOnly;";
                                 statement.execute(sql);
                             } else if (isH2()) {
                                 sql = "GRANT SELECT ON " +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(edgeLabel.getSchema().getName()) + "." +
                                         sqlgGraph.getSqlDialect().maybeWrapInQoutes(Topology.EDGE_PREFIX + edgeLabel.getName()) + " TO READ_ONLY";
                                 statement.execute(sql);
                             } else {
                                 Assert.fail("Not handled");
                             }
                         } catch (SQLException e) {
                             throw new RuntimeException(e);
                         }
                     } else if (topologyInf instanceof Schema schema) {
                         Connection conn = sqlgGraph.tx().getConnection();
                         try (Statement statement = conn.createStatement()) {
                             if (isPostgres()) {
                                 String sql = "GRANT USAGE ON SCHEMA  " + sqlgGraph.getSqlDialect().maybeWrapInQoutes(schema.getName()) + " TO \"sqlgReadOnly\"";
                                 statement.execute(sql);
                             } else if (isMsSqlServer()) {
                                 String sql = "GRANT SELECT ON SCHEMA :: " + sqlgGraph.getSqlDialect().maybeWrapInQoutes(schema.getName()) + " TO sqlgReadOnly";
                                 statement.execute(sql);
                             }
                         } catch (SQLException e) {
                             throw new RuntimeException(e);
                         }
                     }
                     break;
                 case ADD_IN_VERTEX_LABEL_TO_EDGE:
                     break;
                 case DELETE:
                     break;
             }
         }
     }
 }