You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/08/31 12:05:12 UTC

[22/27] jena git commit: JENA-1494: Handle any dataset

JENA-1494: Handle any dataset


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/80a2f7b5
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/80a2f7b5
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/80a2f7b5

Branch: refs/heads/master
Commit: 80a2f7b543137fd35cb1e8c2b55fa432854d5f18
Parents: 2ec9065
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Aug 26 21:46:07 2018 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Aug 26 23:27:13 2018 +0100

----------------------------------------------------------------------
 .../sparql/core/DatasetGraphFilteredView.java   |  3 ++
 .../jena/fuseki/access/DataAccessCtl.java       | 35 +++++++++---------
 .../access/Filtered_SPARQL_QueryDataset.java    | 21 +++++------
 .../jena/fuseki/access/SecurityPolicy.java      |  3 +-
 .../fuseki/access/TestSecurityFilterFuseki.java | 18 ++++++----
 .../fuseki/access/TestSecurityFilterLocal.java  | 38 ++++++++++++--------
 .../apache/jena/fuseki/cmds/FusekiBasicCmd.java |  4 +--
 .../jena/fuseki/servlets/SPARQL_Query.java      |  6 ++--
 8 files changed, 69 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphFilteredView.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphFilteredView.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphFilteredView.java
index 3084e33..4c49bd1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphFilteredView.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphFilteredView.java
@@ -114,6 +114,9 @@ public class DatasetGraphFilteredView extends DatasetGraphReadOnly implements Da
 
     @Override
     public Graph getUnionGraph() {
+        // Does not exploit TDB-isms, but is general.
+        // To exploit TDB, we'd have to modify the dataset
+        // to set union graph but that's not per-request.
         return new GraphUnionRead(this, visibleGraphs);
     }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
index dc8c913..3bc0812 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
@@ -35,20 +35,23 @@ import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFilteredView;
 import org.apache.jena.sparql.util.Context;
 import org.apache.jena.sparql.util.Symbol;
+import org.apache.jena.sys.JenaSystem;
 import org.eclipse.jetty.security.SecurityHandler;
 
 /** A library of operations related to data acess sexurity for Fuseki */  
 public class DataAccessCtl {
-
+    static { JenaSystem.init(); }
+    
     /**
      * Flag for whether this is data access controlled or not - boolean false or undef for "not
-     * controlled".
+     * controlled". This is an alternative to {@link DatasetGraphAccessControl}.
      */
     public static final Symbol   symControlledAccess      = Symbol.create(VocabSecurity.getURI() + "controlled");
     
     /**
      * Symbol for the {@link SecurityRegistry}. Must be present if
      * {@link #symControlledAccess} indicates data access control.
+     * This is an alternative to {@link DatasetGraphAccessControl}.
      */
     public static final Symbol   symSecurityRegistry      = Symbol.create(VocabSecurity.getURI() + "registry");
 
@@ -56,30 +59,26 @@ public class DataAccessCtl {
     public static final Function<HttpAction, String> requestUserServlet = (action)->action.request.getRemoteUser();
 
     /**
+     * Get the user from {@code ?user} query string parameter. Use carefully; for situations where the user name has
+     * been authenticated already and is being passed on securely. Also for testing.
+     */
+    public static final Function<HttpAction, String> paramUserServlet = (action)->action.request.getParameter("user");
+
+    /**
      * Add data access control information on a {@link DatasetGraph}. This modifies the
      * {@link DatasetGraph}'s {@link Context}.
      */
-    private static void controlledDataset(DatasetGraph dsg, SecurityRegistry reg) {
-        // Or wrapper.
+    private static void addSecurityRegistry(DatasetGraph dsg, SecurityRegistry reg) {
         dsg.getContext().set(symControlledAccess, true);
         dsg.getContext().set(symSecurityRegistry, reg);
     }
 
-//    /**
-//     * Enable data access control on a {@link Dataset}. This modifies the
-//     * {@link Dataset}'s {@link Context}.
-//     */
-//    private static void controlledDataset(Dataset ds, SecurityRegistry reg) {
-//        ds.getContext().set(symControlledAccess, true);
-//        ds.getContext().set(symSecurityRegistry, reg);
-//    }
-
     /**
-     * Return a {@link DatasetGraph} with added data access control. Use of the original
-     * {@code DatasetGraph} is not controlled.
+     * Return a {@link DatasetGraph} with added data access control. 
+     * Use of the original {@code DatasetGraph} is not controlled.
      */
-    public static Dataset wrapControlledDataset(Dataset dsBase, SecurityRegistry reg) {
-        DatasetGraph dsg = wrapControlledDataset(dsBase.asDatasetGraph(), reg);
+    public static Dataset controlledDataset(Dataset dsBase, SecurityRegistry reg) {
+        DatasetGraph dsg = controlledDataset(dsBase.asDatasetGraph(), reg);
         return DatasetFactory.wrap(dsg);
     }
     
@@ -87,7 +86,7 @@ public class DataAccessCtl {
      * Return a {@link DatasetGraph} with added data access control. Use of the original
      * {@code DatasetGraph} is not controlled.
      */
-    public static DatasetGraph wrapControlledDataset(DatasetGraph dsgBase, SecurityRegistry reg) {
+    public static DatasetGraph controlledDataset(DatasetGraph dsgBase, SecurityRegistry reg) {
         if ( dsgBase instanceof DatasetGraphAccessControl ) {
             DatasetGraphAccessControl dsgx = (DatasetGraphAccessControl)dsgBase;
             if ( reg == dsgx.getRegistry() )

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/Filtered_SPARQL_QueryDataset.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/Filtered_SPARQL_QueryDataset.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/Filtered_SPARQL_QueryDataset.java
index 49efc4f..8162f91 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/Filtered_SPARQL_QueryDataset.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/Filtered_SPARQL_QueryDataset.java
@@ -18,6 +18,8 @@
 
 package org.apache.jena.fuseki.access;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.function.Function;
 
 import org.apache.jena.fuseki.servlets.ActionService;
@@ -38,6 +40,12 @@ public class Filtered_SPARQL_QueryDataset extends SPARQL_QueryDataset {
     }
 
     @Override
+    protected Collection<String> customParams() {
+        // The additional ?user.
+        return Collections.singletonList("user");
+    }
+    
+    @Override
     protected QueryExecution createQueryExecution(HttpAction action, Query query, Dataset dataset) {
         // Server database, not the possibly dynamically built "dataset"
         DatasetGraph dsg = action.getDataset();
@@ -46,20 +54,9 @@ public class Filtered_SPARQL_QueryDataset extends SPARQL_QueryDataset {
         if ( ! DataAccessCtl.isAccessControlled(dsg) )
             return super.createQueryExecution(action, query, dataset);
 
-        // XXX Generalize to any DSG.
         SecurityPolicy sCxt = DataAccessLib.getSecurityPolicy(action, dataset.asDatasetGraph(), requestUser);
-        
+        // A QueryExecution for controlled access
         QueryExecution qExec = sCxt.createQueryExecution(query, dsg);
-        
-//        if ( dsg instanceof DatasetGraphAccessControl ) {
-//            // Take off one layer.
-//            dsg = DatasetGraphAccessControl.removeWrapper(dsg);
-//            // Add back the Dataset for the createQueryExecution call.
-//            dataset = DatasetFactory.wrap(dsg);
-//        }
-//        QueryExecution qExec = super.createQueryExecution(action, query, dataset);
-//        if ( sCxt != null )
-//            sCxt.filterTDB(dsg, qExec);
         return qExec;
     }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityPolicy.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityPolicy.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityPolicy.java
index c0d420a..ca19794 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityPolicy.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityPolicy.java
@@ -114,8 +114,7 @@ public class SecurityPolicy {
             if ( quad.isDefaultGraph() )
                 return matchDefaultGraph;
             if ( quad.isUnionGraph() ) 
-                // XXX What to do here.
-                // Need special union graph?
+                // Union graph is automatically there but its visible contents are different.
                 return true;
             return graphNames.contains(quad.getGraph());
         };

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
index 7050ef0..c9d188a 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
@@ -41,6 +41,7 @@ import org.apache.jena.rdf.model.RDFNode;
 import org.apache.jena.rdfconnection.RDFConnection;
 import org.apache.jena.rdfconnection.RDFConnectionFactory;
 import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.DatasetGraphFactory;
 import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.engine.http.QueryExceptionHTTP;
 import org.apache.jena.tdb.TDBFactory;
@@ -62,14 +63,17 @@ public class TestSecurityFilterFuseki {
 
     @Parameters(name = "{index}: {0}")
     public static Iterable<Object[]> data() {
-        Object[] obj1 = { "TDB", "data1" };
+        Object[] obj1 = { "TDB",  "data1" };
         Object[] obj2 = { "TDB2", "data2" };
-        return Arrays.asList(obj1, obj2);
+        Object[] obj3 = { "TIM",  "data3" };
+        return Arrays.asList(obj1, obj2, obj3);
     }
 
     private final String baseUrl;
     private static DatasetGraph testdsg1 =  TDBFactory.createDatasetGraph();
     private static DatasetGraph testdsg2 =  DatabaseMgr.createDatasetGraph();
+    private static DatasetGraph testdsg3 =  DatasetGraphFactory.createTxnMem();
+    
     private static FusekiServer fusekiServer;
 
     // Set up Fuseki with two datasets, "data1" backed by TDB and "data2" backed by TDB2.
@@ -77,6 +81,7 @@ public class TestSecurityFilterFuseki {
         int port = FusekiLib.choosePort();
         addTestData(testdsg1);
         addTestData(testdsg2);
+        addTestData(testdsg3);
         
         SecurityRegistry reg = new SecurityRegistry();
         reg.put("userNone", SecurityPolicy.NONE);
@@ -85,10 +90,10 @@ public class TestSecurityFilterFuseki {
         reg.put("user1", new SecurityPolicy("http://test/g1", Quad.defaultGraphIRI.getURI()));
         reg.put("user2", new SecurityPolicy("http://test/g1", "http://test/g2", "http://test/g3"));
         
-        // XXX Also need wrapped tests
-        testdsg1 = DataAccessCtl.wrapControlledDataset(testdsg1, reg);
-        testdsg2 = DataAccessCtl.wrapControlledDataset(testdsg2, reg);
-
+        testdsg1 = DataAccessCtl.controlledDataset(testdsg1, reg);
+        testdsg2 = DataAccessCtl.controlledDataset(testdsg2, reg);
+        testdsg3 = DataAccessCtl.controlledDataset(testdsg3, reg);
+        
         UserStore userStore = userStore();
         SecurityHandler sh = JettyLib.makeSecurityHandler("/*", "DatasetRealm", userStore);
         
@@ -96,6 +101,7 @@ public class TestSecurityFilterFuseki {
             .port(port)
             .add("data1", testdsg1)
             .add("data2", testdsg2)
+            .add("data3", testdsg3)
             .build();
         fusekiServer.start();
     }

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
index 0268b5b..1e03aba 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
@@ -48,8 +48,10 @@ import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFactory;
 import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.system.Txn;
+import org.apache.jena.tdb.TDB;
 import org.apache.jena.tdb.TDBFactory;
 import org.apache.jena.tdb2.DatabaseMgr;
+import org.apache.jena.tdb2.TDB2;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -86,7 +88,7 @@ public class TestSecurityFilterLocal {
     private final DatasetGraph testdsg;
     private SecurityRegistry reg = new SecurityRegistry();
     private final boolean applyFilterDSG;
-    private final boolean applyFilterQExec;
+    private final boolean applyFilterTDB;
     
     public TestSecurityFilterLocal(String name, Creator<DatasetGraph> source, boolean applyFilterTDB) {
         DatasetGraph dsgBase = source.create();
@@ -96,9 +98,9 @@ public class TestSecurityFilterLocal {
         reg.put("user0", new SecurityPolicy(Quad.defaultGraphIRI.getURI()));
         reg.put("user1", new SecurityPolicy("http://test/g1", Quad.defaultGraphIRI.getURI()));
         reg.put("user2", new SecurityPolicy("http://test/g1", "http://test/g2", "http://test/g3"));
-        testdsg = DataAccessCtl.wrapControlledDataset(dsgBase, reg);
+        testdsg = DataAccessCtl.controlledDataset(dsgBase, reg);
+        this.applyFilterTDB = applyFilterTDB;
         this.applyFilterDSG = ! applyFilterTDB;
-        this.applyFilterQExec = applyFilterTDB;
     }
     
     private static void assertSeen(Set<Node> visible, Node ... expected) {
@@ -121,7 +123,7 @@ public class TestSecurityFilterLocal {
         return
             Txn.calculateRead(ds, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryString, ds)) {
-                    if ( applyFilterQExec )
+                    if ( applyFilterTDB )
                         sCxt.filterTDB(dsg1, qExec);
                     List<QuerySolution> results = Iter.toList(qExec.execSelect());
                     Stream<Node> stream = results.stream()
@@ -142,7 +144,7 @@ public class TestSecurityFilterLocal {
         return
             Txn.calculateRead(testdsg, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryString, model)) {
-                    if ( applyFilterQExec )
+                    if ( applyFilterTDB )
                         sCxt.filterTDB(dsg1, qExec);
                     List<QuerySolution> results = Iter.toList(qExec.execSelect());
                     Stream<Node> stream = results.stream().map(qs->qs.get("s")).filter(Objects::nonNull).map(RDFNode::asNode);
@@ -159,7 +161,7 @@ public class TestSecurityFilterLocal {
         return
             Txn.calculateRead(ds, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryGraphNames, ds)) {
-                    if ( applyFilterQExec )
+                    if ( applyFilterTDB )
                         sCxt.filterTDB(dsg1, qExec);
                     List<QuerySolution> results = Iter.toList(qExec.execSelect());
                     Stream<Node> stream = results.stream().map(qs->qs.get("g")).filter(Objects::nonNull).map(RDFNode::asNode);
@@ -251,15 +253,21 @@ public class TestSecurityFilterLocal {
     // QueryExecution w/ Union default graph
     private void filter_union_user(String user, Node ... expected) {
         SecurityPolicy sCxt = reg.get(user);
-        // XXX Need to set union.
-//        Consumer<QueryExecution> modifier = qExec-> {
-//            qExec.getContext().set(TDB.symUnionDefaultGraph, true);
-//            qExec.getContext().set(TDB2.symUnionDefaultGraph, true);
-//            sCxt.filterTDB(testdsg, qExec); 
-//        };
-//        Set<Node> visible = subjects(testdsg, queryDft, sCxt);
-        
-        Set<Node> visible = subjects(testdsg, dsg->dsg.getUnionGraph(), queryDft, sCxt);
+        Set<Node> visible;
+        if ( applyFilterTDB ) {
+            // TDB special version. Set the TDB flags for union default graph
+            try {
+                testdsg.getContext().set(TDB.symUnionDefaultGraph, true);
+                testdsg.getContext().set(TDB2.symUnionDefaultGraph, true);
+                visible = subjects(testdsg, queryDft, sCxt);
+            } finally {
+                // And unset them.
+                testdsg.getContext().unset(TDB.symUnionDefaultGraph);
+                testdsg.getContext().unset(TDB2.symUnionDefaultGraph);
+            }
+        } else {
+            visible = subjects(testdsg, dsg->dsg.getUnionGraph(), queryDft, sCxt);
+        }
         assertSeen(visible, expected);
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-basic/src/main/java/org/apache/jena/fuseki/cmds/FusekiBasicCmd.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-basic/src/main/java/org/apache/jena/fuseki/cmds/FusekiBasicCmd.java b/jena-fuseki2/jena-fuseki-basic/src/main/java/org/apache/jena/fuseki/cmds/FusekiBasicCmd.java
index baa3b28..f1ba1f2 100644
--- a/jena-fuseki2/jena-fuseki-basic/src/main/java/org/apache/jena/fuseki/cmds/FusekiBasicCmd.java
+++ b/jena-fuseki2/jena-fuseki-basic/src/main/java/org/apache/jena/fuseki/cmds/FusekiBasicCmd.java
@@ -510,10 +510,8 @@ public class FusekiBasicCmd {
             }
             
             if ( serverConfig.datasetPath != null ) {
-                if ( mapDatasetEndpoints.size() != 1 ) {
-                    System.err.println(serverConfig.datasetPath);
+                if ( mapDatasetEndpoints.size() != 1 )
                     log.error("Expected only one dataset");
-                }
                 List<String> endpoints = mapDatasetEndpoints.get(serverConfig.datasetPath); 
                 FmtLog.info(log,  "Dataset Type = %s", serverConfig.datasetDescription);
                 FmtLog.info(log,  "Path = %s; Services = %s", serverConfig.datasetPath, endpoints);

http://git-wip-us.apache.org/repos/asf/jena/blob/80a2f7b5/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
index a14e75a..931f27f 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
@@ -108,9 +108,9 @@ public abstract class SPARQL_Query extends SPARQL_Protocol
         if ( acceptedParams_ == null ) {
             synchronized(this) {
                 if ( acceptedParams_ == null )
-                // Does not matter about race condition here because the same Set should be
-                // created on any call to generateAcceptedParams.
-                acceptedParams_ = generateAcceptedParams();
+                    // Does not matter about race condition here because the same Set should be
+                    // created on any call to generateAcceptedParams.
+                    acceptedParams_ = generateAcceptedParams();
             }
         }
         return acceptedParams_;