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;
  }
  }
  }
 }