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/11/17 17:20:35 UTC

[09/34] jena git commit: JENA-1627: Merge access control into Fuseki main

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
new file mode 100644
index 0000000..0a16f5b
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
@@ -0,0 +1,166 @@
+/*
+ * 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.jena.fuseki.access;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.function.Predicate;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.NodeUtils;
+import org.apache.jena.tdb.TDBFactory;
+import org.apache.jena.tdb2.DatabaseMgr;
+
+/** A {@link SecurityContextView} is the things actor (user, role) is allowed to do. 
+ * Currently version: the set of graphs, by graph name, they can access.
+ * It can be inverted into a "deny" policy with {@link Predicate#negate()}.
+ */ 
+public class SecurityContextView implements SecurityContext {
+    
+    public static SecurityContextView NONE = new SecurityContextView();
+    public static SecurityContextView DFT_GRAPH = new SecurityContextView(true);
+
+    private final Collection<Node> graphNames;
+    private final boolean matchDefaultGraph;
+    
+    private SecurityContextView() {
+        this(false);
+    }
+
+    private SecurityContextView(boolean matchDefaultGraph) {
+        this.matchDefaultGraph = matchDefaultGraph;
+        this.graphNames = Collections.emptyList();
+    }
+
+    public SecurityContextView(String...graphNames) {
+        this(NodeUtils.convertToSetNodes(graphNames));
+    }
+
+    public SecurityContextView(Node...graphNames) {
+        this(Arrays.asList(graphNames));
+    }
+
+    public SecurityContextView(Collection<Node> visibleGraphs) {
+        Collection<Node> x = new ArrayList<>();
+        x.addAll(visibleGraphs);
+        this.matchDefaultGraph = visibleGraphs.stream().anyMatch(Quad::isDefaultGraph);
+        if ( matchDefaultGraph ) {
+            x.remove(Quad.defaultGraphIRI);
+            x.remove(Quad.defaultGraphNodeGenerated);
+        }
+        this.graphNames = Collections.unmodifiableCollection(x);
+    }
+    
+    @Override
+    public Collection<Node> visibleGraphs() {
+        return graphNames;
+    }
+    
+    @Override
+    public boolean visableDefaultGraph() {
+        return matchDefaultGraph;
+    }
+
+    @Override
+    public QueryExecution createQueryExecution(String queryString, DatasetGraph dsg) {
+        return createQueryExecution(QueryFactory.create(queryString), dsg);
+    }
+    
+    @Override
+    public QueryExecution createQueryExecution(Query query, DatasetGraph dsg) {
+        if ( isAccessControlledTDB(dsg) ) {
+            QueryExecution qExec = QueryExecutionFactory.create(query, dsg);
+            filterTDB(dsg, qExec);
+            return qExec;
+        }
+        // Not TDB - do by selecting graphs.
+        DatasetGraph dsgA = DataAccessCtl.filteredDataset(dsg, this);
+        return QueryExecutionFactory.create(query, dsgA);
+    }
+    
+    /**
+     * Apply a filter suitable for the TDB-backed {@link DatasetGraph}, to the {@link Context} of the
+     * {@link QueryExecution}. This does not modify the {@link DatasetGraph}
+     */
+    /*package*/ void filterTDB(DatasetGraph dsg, QueryExecution qExec) {
+        GraphFilter<?> predicate = predicate(dsg);
+        qExec.getContext().set(predicate.getContextKey(), predicate);
+    }
+
+    /**
+     * Quad filter to reflect the security policy of this {@link SecurityContext}. It is
+     * better to call {@link #createQueryExecution(Query, DatasetGraph)} which may be more
+     * efficient.
+     */
+    @Override
+    public Predicate<Quad> predicateQuad() {
+        return quad -> {
+            if ( quad.isDefaultGraph() )
+                return matchDefaultGraph;
+            if ( quad.isUnionGraph() ) 
+                // Union graph is automatically there but its visible contents are different.
+                return true;
+            return graphNames.contains(quad.getGraph());
+        };
+    }
+
+    /**
+     * Create a GraphFilter for a TDB backed dataset.
+     * 
+     * @return GraphFilter
+     * @throws IllegalArgumentException
+     *             if not a TDB database, or a {@link DatasetGraphAccessControl} wrapped
+     *             TDB database.
+     */
+    private GraphFilter<?> predicate(DatasetGraph dsg) {
+        dsg = DatasetGraphAccessControl.removeWrapper(dsg);
+        // dsg has to be the database dataset, not wrapped.
+        //  DatasetGraphSwitchable is wrapped but should not be unwrapped. 
+        if ( TDBFactory.isTDB1(dsg) )
+            return GraphFilterTDB1.graphFilter(dsg, graphNames, matchDefaultGraph);
+        if ( DatabaseMgr.isTDB2(dsg) )
+            return GraphFilterTDB2.graphFilter(dsg, graphNames, matchDefaultGraph);
+        throw new IllegalArgumentException("Not a TDB1 or TDB2 database: "+dsg.getClass().getSimpleName());
+    }
+
+    private static boolean isAccessControlledTDB(DatasetGraph dsg) {
+        DatasetGraph dsgBase = DatasetGraphAccessControl.unwrapOrNull(dsg);
+        if ( dsgBase == null )
+            return false;
+        if ( TDBFactory.isTDB1(dsgBase) )
+            return true;
+        if ( DatabaseMgr.isTDB2(dsgBase) )
+            return true;
+        return false;
+    }
+    
+    @Override
+    public String toString() {
+        return "dft:"+matchDefaultGraph+" / "+graphNames.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
index 7629cd2..1810d1a 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
@@ -23,9 +23,9 @@ import java.util.StringJoiner;
 import org.apache.jena.atlas.lib.Registry;
 
 /**
- * Am {@link AuthorizationService} implements as a mapping from a string (typically a user name or role
+ * A registry mapping from a string (typically a user name or role
  * name) to a {@link SecurityContext}, where the {@link SecurityContext}
- * is the access control operations for the user/role.
+ * is the access control operations for that user/role.
  */ 
 public class SecurityRegistry extends Registry<String, SecurityContext> implements AuthorizationService {
     

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestGraphSecurityAssembler.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestGraphSecurityAssembler.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestGraphSecurityAssembler.java
deleted file mode 100644
index 1335702..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestGraphSecurityAssembler.java
+++ /dev/null
@@ -1,326 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.apache.jena.fuseki.access.AccessTestLib.assertSeen;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.jena.atlas.iterator.Iter;
-import org.apache.jena.atlas.lib.SetUtils;
-import org.apache.jena.atlas.lib.StrUtils;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.fuseki.main.FusekiServer;
-import org.apache.jena.fuseki.system.FusekiNetLib;
-import org.apache.jena.graph.Node;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.query.QuerySolution;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.RDFNode;
-import org.apache.jena.rdf.model.Resource;
-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.Quad;
-import org.apache.jena.sparql.sse.SSE;
-import org.apache.jena.sys.JenaSystem;
-import org.apache.jena.system.Txn;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test on the assembler for data access control.
- * <ul>
- * <li>assem-security.ttl - two services "/database" and "/plain" each with their own dataset. 
- * <li>assem-security-shared.ttl - two services "/database" and "/plain" with a shared dataset.
- * </ul>
- * 
- * @see TestSecurityFilterFuseki TestSecurityFilterFuseki for other HTTP tests.
- */
-
-public abstract class AbstractTestGraphSecurityAssembler {
-    static { JenaSystem.init(); }
-    static final String DIR = "testing/Access/";
-
-//    @Parameters(name = "{index}: {0}")
-//    public static Iterable<Object[]> data() {
-//        Object[] obj1 = { DIR+"assem-security.ttl" , false };
-//        Object[] obj2 = { DIR+"assem-security-shared.ttl" , true };
-//        return Arrays.asList(obj1, obj2);
-//    }
-
-    private final String assemblerFile;
-    private static AtomicReference<String> user = new AtomicReference<>();
-
-    private boolean sharedDatabase;
-
-    // Parameterized tests don't provide a convenient way to run code at the start and end of each parameter run and access the parameters. 
-    private static FusekiServer server;
-    private FusekiServer getServer() {
-        if ( server == null )
-            server = setup(assemblerFile, false);
-        return server;
-    }
-    @AfterClass public static void afterClass() {
-        server.stop();
-        server = null;
-        user.set(null);
-    }
-    
-    @Before
-    public void before() {
-        user.set(null);
-    }
-    
-    private String getURL() {
-        getServer();
-        int port = server.getPort();
-        return "http://localhost:"+port+"/database";
-    }
-    
-    private static FusekiServer setup(String assembler, boolean sharedDatabase) {
-        int port = FusekiNetLib.choosePort();
-        FusekiServer server = DataAccessCtl.fusekiBuilder((a)->user.get())
-            .port(port)
-            .parseConfigFile(assembler)
-            .build();
-        server.start();
-        
-        if ( sharedDatabase ) {
-            String data = StrUtils.strjoinNL
-                ("PREFIX : <http://example/>"
-                ,"INSERT DATA {"
-                ,"   :s0 :p :o ."
-                ,"   GRAPH <http://host/graphname1> {:s1 :p :o}"
-                ,"   GRAPH <http://host/graphname3> {:s3 :p :o}"
-                ,"   GRAPH <http://host/graphname9> {:s9 :p :o}"
-                ,"}"
-                );
-            String plainUrl = "http://localhost:"+server.getPort()+"/plain";
-            try(RDFConnection conn = RDFConnectionFactory.connect(plainUrl)) {
-                conn.update(data);
-            }
-        } else {
-            DatasetGraph dsg = server.getDataAccessPointRegistry().get("/database").getDataService().getDataset();
-            Txn.executeWrite(dsg,  ()->{
-                dsg.add(SSE.parseQuad("(<http://host/graphname1> :s1 :p :o)"));
-                dsg.add(SSE.parseQuad("(<http://host/graphname3> :s3 :p :o)"));
-                dsg.add(SSE.parseQuad("(<http://host/graphname9> :s9 :p :o)"));
-            });
-        }
-        return server;
-    }
-    
-    protected AbstractTestGraphSecurityAssembler(String assemberFile, boolean sharedDatabase) {
-        this.assemblerFile = assemberFile;
-        this.sharedDatabase = sharedDatabase ;
-    }
-
-    private static Node s1 = SSE.parseNode(":s1"); 
-    private static Node s2 = SSE.parseNode(":s2"); 
-    private static Node s3 = SSE.parseNode(":s3");
-    private static Node s9 = SSE.parseNode(":s9"); 
-
-        // The access controlled dataset.
-
-//        { SecurityRegistry
-//            user1 -> dft:false / [http://host/graphname2, http://host/graphname1, http://host/graphname3]
-//            user2 -> dft:false / [http://host/graphname9]
-//            userZ -> dft:false / [http://host/graphnameZ]
-//            user3 -> dft:false / [http://host/graphname4, http://host/graphname3, http://host/graphname5]
-//          }
-        
-        
-    @Test public void query_user1() {         
-        user.set("user1");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = query(conn, "SELECT * { GRAPH ?g { ?s ?p ?o }}");
-            assertSeen(visible, s1, s3);
-        }
-    }
-
-    @Test public void query_userX() {
-        user.set("userX"); // No such user in the registry
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = query(conn, "SELECT * { GRAPH ?g { ?s ?p ?o }}");
-            assertSeen(visible);
-        }
-    }
-    
-    @Test public void query_no_user() {
-        user.set(null); // No user.
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = query(conn, "SELECT * { GRAPH ?g { ?s ?p ?o }}");
-            assertSeen(visible);
-        }
-    }
-    
-    @Test public void query_user2() {
-        user.set("user2");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = query(conn, "SELECT * { GRAPH ?g { ?s ?p ?o }}");
-            assertSeen(visible, s9);
-        }
-    }
-    
-    @Test public void query_userZ() {
-        user.set("userZ"); // No graphs with data.
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = query(conn, "SELECT * { GRAPH ?g { ?s ?p ?o }}");
-            assertSeen(visible);
-        }
-    }
-    
-    // GSP. "http://host/graphname1"
-    @Test public void gsp_dft_user1() {
-        user.set("user1");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = gsp(conn, null);
-            assertSeen(visible);
-        }
-    }
-    
-    @Test public void gsp_ng_user1() {
-        user.set("user1");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            Set<Node> visible = gsp(conn, "http://host/graphname1");
-            assertSeen(visible, s1);
-        }
-    }
-    
-    @Test public void gsp_dft_user2() {
-        user.set("user2");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, null);
-        }
-    }
-    
-    @Test public void gsp_ng_user2() {
-        user.set("user2");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, "http://host/graphname1");
-        }
-    }
-    
-    @Test public void gsp_dft_userX() {
-        user.set("userX");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, null);
-        }
-    }
-    
-    @Test public void gsp_ng_userX() {
-        user.set("userX");
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, "http://host/graphname1");
-        }
-    }
-
-    @Test public void gsp_dft_user_null() {
-        user.set(null);
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, null);
-        }
-    }
-    
-    @Test public void gsp_ng_user_null() {
-        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-            gsp404(conn, "http://host/graphname1");
-        }
-    }
-    
-//        // Quads
-//        user.set("user1");
-//        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-//            Set<Node> visible = dataset(conn);
-//            assertSeen(visible, s1, s3);
-//        }
-//        user.set("user2");
-//        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-//            Set<Node> visible = dataset(conn);
-//            assertSeen(visible, s9);
-//        }
-//        user.set("userX");
-//        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-//            Set<Node> visible = dataset(conn);
-//            assertSeen(visible);
-//        }
-//        user.set(null);
-//        try(RDFConnection conn = RDFConnectionFactory.connect(getURL())) {
-//            Set<Node> visible = dataset(conn);
-//            assertSeen(visible);
-//        }
-
-
-    private Set<Node> gsp(RDFConnection conn, String graphName) {
-        Set<Node> results = new HashSet<>();
-        Model model = graphName == null ? conn.fetch() : conn.fetch(graphName);
-        // Extract subjects.
-        Set<Node> seen = 
-            SetUtils.toSet(
-                Iter.asStream(model.listSubjects())
-                    .map(Resource::asNode)
-                );
-        return seen;
-    }
-
-    private void gsp404(RDFConnection conn, String graphName) {
-        gspHttp(conn, 404, graphName);
-    }
-
-    private void gspHttp(RDFConnection conn, int statusCode, String graphName) {
-        try {
-            gsp(conn, graphName);
-            if ( statusCode < 200 && statusCode > 299 ) 
-                fail("Should have responded with "+statusCode);
-        } catch (HttpException ex) {
-            assertEquals(statusCode, ex.getResponseCode());
-        }
-    }
-    
-    private Set<Node> dataset(RDFConnection conn) {
-        Dataset ds = conn.fetchDataset();
-        Set<Node> seen = 
-            SetUtils.toSet(
-                Iter.asStream(ds.asDatasetGraph().find())
-                    .map(Quad::getSubject)
-                    );
-        return seen;     
-    }
-
-    private Set<Node> query(RDFConnection conn, String queryString) {
-        Set<Node> results = new HashSet<>();
-        conn.queryResultSet(queryString, rs->{
-            List<QuerySolution> list = Iter.toList(rs);
-            list.stream()
-                .map(qs->qs.get("s"))
-                .filter(Objects::nonNull)
-                .map(RDFNode::asNode)
-                .forEach(n->results.add(n));
-        });
-        return results;
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AccessTestLib.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AccessTestLib.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AccessTestLib.java
deleted file mode 100644
index e95a3e9..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AccessTestLib.java
+++ /dev/null
@@ -1,70 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.jena.atlas.lib.StrUtils;
-import org.apache.jena.graph.Node;
-import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFParser;
-import org.apache.jena.sparql.core.DatasetGraph;
-import org.apache.jena.sparql.sse.SSE;
-import org.apache.jena.system.Txn;
-
-
-/** Some data and functions common to access control tests. */ 
-public class AccessTestLib {
-    private static String dataStr = StrUtils.strjoinNL 
-        ("PREFIX : <http://test/>"
-            ,""
-            ,":s0 :p 0 ."
-            ,":g1 { :s1 :p 1 }"
-            ,":g2 { :s2 :p 2 }"
-            ,":g3 { :s3 :p 3 }"
-            ,":g4 { :s4 :p 4 }"
-            );
-
-
-    public static Node s0 = SSE.parseNode("<http://test/s0>"); 
-    public static Node s1 = SSE.parseNode("<http://test/s1>"); 
-    public static Node s2 = SSE.parseNode("<http://test/s2>"); 
-    public static Node s3 = SSE.parseNode("<http://test/s3>"); 
-    public static Node s4 = SSE.parseNode("<http://test/s4>"); 
-
-    public static Node g1 = SSE.parseNode("<http://test/g1>"); 
-    public static Node g2 = SSE.parseNode("<http://test/g2>"); 
-    public static Node g3 = SSE.parseNode("<http://test/g3>"); 
-    public static Node g4 = SSE.parseNode("<http://test/g4>"); 
-
-    public static void addTestData(DatasetGraph dsg) {
-        Txn.executeWrite(dsg, ()->{
-            RDFParser.create().fromString(dataStr).lang(Lang.TRIG).parse(dsg);
-        });
-    }
-    
-    public static void assertSeen(Set<Node> visible, Node ... expected) {
-        Set<Node> expectedNodes = new HashSet<>(Arrays.asList(expected));
-        assertEquals(expectedNodes, visible);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
new file mode 100644
index 0000000..cf719ac
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
@@ -0,0 +1,33 @@
+/*
+ * 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.jena.fuseki.access;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( {
+    // Much of testing can only be done with a running server.
+    // These integration test are in jena-fuseki-main:org.apache.jena.fuseki.main.access
+    TestSecurityFilterLocal.class
+    , TestServiceRegistry.class
+})
+    
+public class TS_Access {
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_SecurityFiltering.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_SecurityFiltering.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_SecurityFiltering.java
deleted file mode 100644
index 19987f8..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_SecurityFiltering.java
+++ /dev/null
@@ -1,50 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import org.apache.jena.atlas.logging.LogCtl;
-import org.apache.jena.fuseki.Fuseki;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses( {
-    TestAuthorizedRequest.class
-    
-    , TestSecurityFilterLocal.class
-    , TestSecurityFilterFuseki.class
-    
-    , TestSecurityAssemblerBuild.class
-    , TestGraphSecurityAssemblerSeparate.class
-    , TestGraphSecurityAssemblerShared.class
-    
-    , TestPasswordServer.class
-    , TestPasswordServices.class
-})
-
-public class TS_SecurityFiltering {
-    @BeforeClass public static void setupForFusekiServer() {
-        LogCtl.setLevel(Fuseki.serverLogName,   "WARN");
-        LogCtl.setLevel(Fuseki.actionLogName,   "WARN");
-        LogCtl.setLevel(Fuseki.requestLogName,  "WARN");
-        LogCtl.setLevel(Fuseki.adminLogName,    "WARN");
-        LogCtl.setLevel("org.eclipse.jetty",    "WARN");
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestAuthorizedRequest.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestAuthorizedRequest.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestAuthorizedRequest.java
deleted file mode 100644
index 480708f..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestAuthorizedRequest.java
+++ /dev/null
@@ -1,111 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.jena.fuseki.build.FusekiBuilder;
-import org.apache.jena.fuseki.build.RequestAuthorization;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.Resource;
-import org.apache.jena.riot.RDFDataMgr;
-import org.junit.Test;
-
-public class TestAuthorizedRequest {
-    
-    static Model model = RDFDataMgr.loadModel("testing/Access/allowedUsers.ttl");
-
-    
-    @Test public void authrequest_anon() {
-        RequestAuthorization req = RequestAuthorization.policyAllowAnon();
-        assertTrue(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-    }
-    
-    @Test public void authrequest_anyLoggedIn_1() {
-        RequestAuthorization req = RequestAuthorization.policyAllowAuthenticated();
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-    }
-    
-    @Test public void authrequest_anyLoggedIn_2() {
-        RequestAuthorization req = RequestAuthorization.policyAllowSpecific("*");
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-    }
-
-    @Test public void authrequest_noOne() {
-        RequestAuthorization req = RequestAuthorization.policyNoAccess();
-        assertFalse(req.isAllowed(null));
-        assertFalse(req.isAllowed("user1"));
-    }
-
-
-    @Test public void authrequest_user_1() {
-        RequestAuthorization req = RequestAuthorization.policyAllowSpecific("user1", "user2");
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-        assertTrue(req.isAllowed("user2"));
-        assertFalse(req.isAllowed("user3"));
-    }
-    
-    @Test public void authrequest_parse_no_info_1() {
-        Resource r = model.createResource("http://example/notInData");
-        RequestAuthorization req = FusekiBuilder.allowedUsers(r);
-        assertNull(req);
-    }
-
-    @Test public void authrequest_parse_no_info_2() {
-        Resource r = model.createResource("http://example/none");
-        RequestAuthorization req = FusekiBuilder.allowedUsers(r);
-        assertNull(req);
-    }
-
-    @Test public void authrequest_parse_1() {
-        Resource r = model.createResource("http://example/r1");
-        RequestAuthorization req = FusekiBuilder.allowedUsers(r);
-        assertNotNull(req);
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-        assertTrue(req.isAllowed("user2"));
-        assertFalse(req.isAllowed("user3"));
-    }
-    
-    @Test public void authrequest_parse_2() {
-        Resource r = model.createResource("http://example/r2");
-        RequestAuthorization req = FusekiBuilder.allowedUsers(r);
-        assertNotNull(req);
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-        assertTrue(req.isAllowed("user2"));
-        assertFalse(req.isAllowed("user3"));
-    }
-    
-    @Test public void authrequest_parse_loggedIn() {
-        Resource r = model.createResource("http://example/rLoggedIn");
-        RequestAuthorization req = FusekiBuilder.allowedUsers(r);
-        assertNotNull(req);
-        assertFalse(req.isAllowed(null));
-        assertTrue(req.isAllowed("user1"));
-        assertTrue(req.isAllowed("user3"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerSeparate.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerSeparate.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerSeparate.java
deleted file mode 100644
index dbf0456..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerSeparate.java
+++ /dev/null
@@ -1,26 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-public class TestGraphSecurityAssemblerSeparate extends AbstractTestGraphSecurityAssembler {
-
-    public TestGraphSecurityAssemblerSeparate() {
-        super(DIR+"assem-security.ttl", false);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerShared.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerShared.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerShared.java
deleted file mode 100644
index 0f55302..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestGraphSecurityAssemblerShared.java
+++ /dev/null
@@ -1,26 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-public class TestGraphSecurityAssemblerShared extends AbstractTestGraphSecurityAssembler {
-
-    public TestGraphSecurityAssemblerShared() {
-        super(DIR+"assem-security-shared.ttl", true);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServer.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServer.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServer.java
deleted file mode 100644
index b160db2..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServer.java
+++ /dev/null
@@ -1,217 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.junit.Assert.assertNull;
-
-import org.apache.http.client.HttpClient;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.atlas.web.TypedInputStream;
-import org.apache.jena.atlas.web.WebLib;
-import org.apache.jena.fuseki.jetty.JettyLib;
-import org.apache.jena.fuseki.main.FusekiServer;
-import org.apache.jena.rdfconnection.RDFConnection;
-import org.apache.jena.rdfconnection.RDFConnectionRemote;
-import org.apache.jena.riot.web.HttpOp;
-import org.apache.jena.sparql.engine.http.QueryExceptionHTTP;
-import org.apache.jena.web.HttpSC;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.UserStore;
-import org.junit.After;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/** Tests for
- * <ul> 
- * <li>password access at the server-level
- * <li>assembler file 
- * </ul> 
- */
-public class TestPasswordServer {
-
-    // Per test.
-    private FusekiServer fusekiServer = null;
-    
-    private static String REALM = "TripleStore";
-    private AuthSetup authSetup1(FusekiServer server) { return new AuthSetup("localhost", server.getPort(), "user1", "pw1", REALM); }
-    private AuthSetup authSetup2(FusekiServer server) { return new AuthSetup("localhost", server.getPort(), "user2", "pw2", REALM); }
-    private AuthSetup authSetup3(FusekiServer server) { return new AuthSetup("localhost", server.getPort(), "user3", "pw3", REALM); }
-    // Not in the user store.
-    private AuthSetup authSetupX(FusekiServer server) { return new AuthSetup("localhost", server.getPort(), "userX", "pwX", REALM); }
-    
-    private static String serverURL(FusekiServer server) {
-        return "http://localhost:"+server.getPort()+"/";
-    }
-    
-    private FusekiServer fusekiServer(String configFile) {
-        int port = WebLib.choosePort();
-        // Read from assembler+passwd file.
-        UserStore userStore = JettyLib.makeUserStore("testing/Access/passwd");
-        ConstraintSecurityHandler sh = JettyLib.makeSecurityHandler(REALM, userStore);
-        
-        fusekiServer =
-            FusekiServer.create()
-                .port(port)
-                .parseConfigFile(configFile)
-                .securityHandler(sh)
-                //.staticFileBase(".")
-                .build();
-        fusekiServer.start();
-        return fusekiServer;
-    }
-    
-    @BeforeClass
-    public static void beforeClass() {
-        // Reset before every test and after the suite.
-        HttpClient hc = HttpOp.createDefaultHttpClient();
-        HttpOp.setDefaultHttpClient(hc);
-    }
-    
-    @After
-    public void after() {
-        if ( fusekiServer != null )
-            fusekiServer.stop();
-        HttpClient hc = HttpOp.createDefaultHttpClient();
-        HttpOp.setDefaultHttpClient(hc);
-    }
-    
-    private static void expectQuery403(Runnable action) {
-        try{
-            action.run();
-            throw new HttpException("action completed");
-        } catch (QueryExceptionHTTP ex) {
-            // 404 is OK - no static file area. 
-            if ( ex.getResponseCode() != HttpSC.FORBIDDEN_403 )
-                throw ex;
-        }
-    }
-    
-    // Server authentication.
-
-    @Test public void access_serverAny_user1() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-1.ttl");
-        try { 
-            // Must be logged in.
-            HttpClient hc = LibSec.httpClient(authSetup1(fusekiServer));
-            try( TypedInputStream in = HttpOp.execHttpGet(serverURL(fusekiServer), null, hc, null) ) {
-                assertNull(in);
-            } catch (HttpException ex) {
-                // 404 is OK - no static file area. 
-                if ( ex.getResponseCode() != HttpSC.NOT_FOUND_404 )
-                    throw ex;
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-    
-    @Test public void access_serverAny_db1() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-1.ttl");
-        try { 
-            // Must be logged in.
-            HttpClient hc = LibSec.httpClient(authSetup1(fusekiServer));
-            try ( RDFConnection conn = RDFConnectionRemote
-                    .create().destination(serverURL(fusekiServer)+"/database1").httpClient(hc).build() ) {
-                conn.queryAsk("ASK{}");
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-
-    @Test public void access_serverAny_db2() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-1.ttl");
-        try { 
-            // Must be logged in.
-            HttpClient hc = LibSec.httpClient(authSetup1(fusekiServer));
-            try ( RDFConnection conn = RDFConnectionRemote
-                    .create().destination(serverURL(fusekiServer)+"/database2").httpClient(hc).build() ) {
-                conn.queryAsk("ASK{}");
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-    
-    @Test public void access_serverAny_db1_wrongUser() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-1.ttl");
-        try { 
-            // Must be logged in.
-            HttpClient hc = LibSec.httpClient(authSetup2(fusekiServer)); // 2
-            try ( RDFConnection conn = RDFConnectionRemote
-                        .create().destination(serverURL(fusekiServer)+"/database1").httpClient(hc).build() ) {
-                expectQuery403(()->conn.queryAsk("ASK{}"));
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-
-    // Specific server user.
-    @Test public void access_serverUser_user1() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-2.ttl");
-        try { 
-            // Must be logged in as user1
-            HttpClient hc = LibSec.httpClient(authSetup1(fusekiServer));
-            try ( RDFConnection conn = RDFConnectionRemote
-                    .create().destination(serverURL(fusekiServer)+"/database1").httpClient(hc).build() ) {
-                conn.queryAsk("ASK{}");
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-    
-    // Specific server user.
-    @Test public void access_serverUser_user2() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-2.ttl");
-        try { 
-            // user2 does not have service access 
-            HttpClient hc = LibSec.httpClient(authSetup2(fusekiServer));
-            try ( RDFConnection conn = RDFConnectionRemote
-                    .create().destination(serverURL(fusekiServer)+"/database1").httpClient(hc).build() ) {
-                expectQuery403(()->conn.queryAsk("ASK{}"));
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-    
-    // Specific server user.
-    @Test public void access_serverUser_user3() {
-        FusekiServer fusekiServer = fusekiServer("testing/Access/config-server-2.ttl");
-        try { 
-            // user3 does not have server access 
-            HttpClient hc = LibSec.httpClient(authSetup3(fusekiServer));
-            try ( RDFConnection conn = RDFConnectionRemote
-                    .create().destination(serverURL(fusekiServer)+"/database1").httpClient(hc).build() ) {
-                expectQuery403(()->conn.queryAsk("ASK{}"));
-            }
-        } finally {
-            fusekiServer.stop();
-            fusekiServer = null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServices.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServices.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServices.java
deleted file mode 100644
index 0183728..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestPasswordServices.java
+++ /dev/null
@@ -1,230 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import org.apache.http.client.HttpClient;
-import org.apache.jena.atlas.logging.LogCtl;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.atlas.web.TypedInputStream;
-import org.apache.jena.atlas.web.WebLib;
-import org.apache.jena.fuseki.build.FusekiBuilder;
-import org.apache.jena.fuseki.build.RequestAuthorization;
-import org.apache.jena.fuseki.jetty.JettyLib;
-import org.apache.jena.fuseki.main.FusekiServer;
-import org.apache.jena.fuseki.server.DataService;
-import org.apache.jena.query.DatasetFactory;
-import org.apache.jena.riot.web.HttpCaptureResponse;
-import org.apache.jena.riot.web.HttpOp;
-import org.apache.jena.riot.web.HttpOp.CaptureInput;
-import org.apache.jena.sparql.core.DatasetGraphFactory;
-import org.apache.jena.web.HttpSC;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.UserStore;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/**
- * Tests for password access to services when there is no server-level access control
- * and also programmatic setup.
- * <p>
- * See {@link TestPasswordServer} for tests with server-level access control
- * and also access control by assembler
- * <p>
- * See {@link TestSecurityFilterFuseki} for graph-level access control.
- *
- */
-public class TestPasswordServices {
-
-    private static FusekiServer fusekiServer = null;
-    private static int port = WebLib.choosePort();
-    private static String serverURL = "http://localhost:"+port+"/";
-    private static AuthSetup authSetup1 = new AuthSetup("localhost", port, "user1", "pw1", "TripleStore");
-    private static AuthSetup authSetup2 = new AuthSetup("localhost", port, "user2", "pw2", "TripleStore");
-    // Not in the user store.
-    private static AuthSetup authSetupX = new AuthSetup("localhost", port, "userX", "pwX", "TripleStore");
-    
-    @BeforeClass
-    public static void beforeClass() {
-        if ( false )
-            // To watch the HTTP headers
-            LogCtl.enable("org.apache.http.headers");
-        
-        // Two authorized users.
-        UserStore userStore = new UserStore();
-        JettyLib.addUser(userStore, authSetup1.user, authSetup1.password);
-        JettyLib.addUser(userStore, authSetup2.user, authSetup2.password);
-        try { userStore.start(); }
-        catch (Exception ex) { throw new RuntimeException("UserStore", ex); }
-        
-        ConstraintSecurityHandler sh = JettyLib.makeSecurityHandler(authSetup1.realm, userStore);
-        
-        // Secure these areas.
-        // User needs to be logged in.
-        JettyLib.addPathConstraint(sh, "/ds");
-        // Allow auth control even through there isn't anything there 
-        JettyLib.addPathConstraint(sh, "/nowhere");
-        // user1 only.
-        JettyLib.addPathConstraint(sh, "/ctl");
-        
-        // Not controlled: "/open"
-        
-        DataService dSrv = new DataService(DatasetGraphFactory.createTxnMem());
-        FusekiBuilder.populateStdServices(dSrv, false);
-        RequestAuthorization reqAuth = RequestAuthorization.policyAllowSpecific("user1");
-        dSrv.setAllowedUsers(reqAuth);
-        
-        fusekiServer =
-            FusekiServer.create()
-                .port(port)
-                .add("/ds", DatasetFactory.createTxnMem())
-                .add("/open", DatasetFactory.createTxnMem())
-                .add("/ctl", dSrv)
-                .securityHandler(sh)
-                //.staticFileBase(".")
-                .build();
-        fusekiServer.start();
-    }
-    
-    @Before
-    public void before() {
-        // Reset before every test and after the suite.
-        HttpClient hc = HttpOp.createDefaultHttpClient();
-        HttpOp.setDefaultHttpClient(hc);
-    }
-    
-
-    @AfterClass
-    public static void afterClass() {
-        fusekiServer.stop();
-        HttpClient hc = HttpOp.createDefaultHttpClient();
-        HttpOp.setDefaultHttpClient(hc);
-    }
-    
-    // Server authentication.
-    
-    @Test public void access_server() {
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL) ) {
-            assertNotNull(in);
-            fail("Didn't expect to succeed");
-        } catch (HttpException ex) {
-            // 404 is OK - no static file area. 
-            if ( ex.getResponseCode() != HttpSC.NOT_FOUND_404 )
-                throw ex;
-        }
-    }
-
-    @Test public void access_open() {
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"open") ) {
-            assertNotNull(in);
-        }
-    }
-
-    @Test public void access_open_user1() {
-        // OK.
-        LibSec.withAuth(serverURL+"open", authSetup1, (conn)->{
-            conn.queryAsk("ASK{}");
-        });
-    }
-
-    @Test public void access_open_userX() {
-        // OK.
-        LibSec.withAuth(serverURL+"open", authSetupX, (conn)->{
-            conn.queryAsk("ASK{}");
-        });
-    }
-
-
-    // Should fail.
-    @Test public void access_deny_ds() {
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"ds") ) {
-            fail("Didn't expect to succeed");
-        } catch (HttpException ex) {
-            if ( ex.getResponseCode() != HttpSC.UNAUTHORIZED_401 )
-                throw ex;
-        }
-    }
-    
-    // Should be 401, not be 404.
-    @Test public void access_deny_nowhere() {
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"nowhere") ) {
-            fail("Didn't expect to succeed");
-        } catch (HttpException ex) {
-            if ( ex.getResponseCode() != HttpSC.UNAUTHORIZED_401 )
-                throw ex;
-        }
-    }
-    
-    @Test public void access_allow_nowhere() {
-        HttpClient hc = LibSec.httpClient(authSetup1);
-        HttpCaptureResponse<TypedInputStream> handler = new CaptureInput();
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"nowhere", null, hc, null) ) {
-            // null for 404.
-            assertNull(in);
-        } catch (HttpException ex) {
-            if ( ex.getResponseCode() != HttpSC.NOT_FOUND_404)
-                throw ex;
-        }
-    }
-    
-    @Test public void access_allow_ds() {
-        HttpClient hc = LibSec.httpClient(authSetup1);
-        HttpCaptureResponse<TypedInputStream> handler = new CaptureInput();
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"ds", null, hc, null) ) {
-            assertNotNull(in);
-        }
-    }
-    
-    // Service level : ctl.
-    
-    @Test public void access_service_ctl_user1() {
-        // user1 -- allowed.
-        HttpClient hc = LibSec.httpClient(authSetup1);
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"ctl", null, hc, null) ) {
-            assertNotNull(in);
-        }
-    }
-    
-    @Test public void access_service_ctl_user2() {
-        // user2 -- can login, not allowed.
-        HttpClient hc = LibSec.httpClient(authSetup2);
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"ctl", null, hc, null) ) {
-            fail("Didn't expect to succeed");
-        } catch (HttpException ex) {
-            if ( ex.getResponseCode() != HttpSC.FORBIDDEN_403)
-                throw ex;
-        }
-    }
-
-    @Test public void access_service_ctl_userX() {
-        // userX -- can't login, not allowed.
-        HttpClient hc = LibSec.httpClient(authSetupX);
-        try( TypedInputStream in = HttpOp.execHttpGet(serverURL+"ctl", null, hc, null) ) {
-            fail("Didn't expect to succeed");
-        } catch (HttpException ex) {
-            if ( ex.getResponseCode() != HttpSC.UNAUTHORIZED_401)
-                throw ex;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityAssemblerBuild.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityAssemblerBuild.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityAssemblerBuild.java
deleted file mode 100644
index ade838b..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityAssemblerBuild.java
+++ /dev/null
@@ -1,47 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.apache.jena.query.Dataset;
-import org.apache.jena.sparql.core.assembler.AssemblerUtils;
-import org.apache.jena.sys.JenaSystem;
-import org.junit.Test;
-
-/** Test parsing of assembers with security aspects */ 
-public class TestSecurityAssemblerBuild {
-    static { JenaSystem.init(); }
-    static final String DIR = "testing/Access/";
-
-    @Test public void assembler1() {
-        assemblerFile(DIR+"assem-security.ttl");
-    }
-    
-    @Test public void assembler2() {
-        assemblerFile(DIR+"assem-security-shared.ttl");
-    }
-    
-    private void assemblerFile(String assemblerFile) { 
-        Dataset ds = (Dataset)AssemblerUtils.build(assemblerFile, VocabSecurity.tAccessControlledDataset);
-        DatasetGraphAccessControl dsg = (DatasetGraphAccessControl)ds.asDatasetGraph();
-        AuthorizationService securityRegistry = dsg.getAuthService();
-        assertNotNull(securityRegistry);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/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
deleted file mode 100644
index 00febf7..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
+++ /dev/null
@@ -1,345 +0,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.
- */
-
-package org.apache.jena.fuseki.access;
-
-import static org.apache.jena.fuseki.access.AccessTestLib.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.util.*;
-
-import org.apache.jena.atlas.iterator.Iter;
-import org.apache.jena.atlas.lib.SetUtils;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.fuseki.jetty.JettyLib;
-import org.apache.jena.fuseki.main.FusekiServer;
-import org.apache.jena.fuseki.system.FusekiNetLib;
-import org.apache.jena.graph.Node;
-import org.apache.jena.query.QuerySolution;
-import org.apache.jena.rdf.model.Model;
-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;
-import org.apache.jena.tdb2.DatabaseMgr;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.PropertyUserStore;
-import org.eclipse.jetty.security.UserStore;
-import org.eclipse.jetty.util.security.Credential;
-import org.eclipse.jetty.util.security.Password;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TestSecurityFilterFuseki {
-
-    @Parameters(name = "{index}: {0}")
-    public static Iterable<Object[]> data() {
-        Object[] obj1 = { "TDB",  "data1" };
-        Object[] obj2 = { "TDB2", "data2" };
-        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.
-    @BeforeClass public static void beforeClass() {
-        int port = FusekiNetLib.choosePort();
-        addTestData(testdsg1);
-        addTestData(testdsg2);
-        addTestData(testdsg3);
-        
-        SecurityRegistry reg = new SecurityRegistry();
-        reg.put("userNone", SecurityContext.NONE);
-        reg.put("userDft", SecurityContext.DFT_GRAPH);
-        reg.put("user0", new SecurityContext(Quad.defaultGraphIRI.getURI()));
-        reg.put("user1", new SecurityContext("http://test/g1", Quad.defaultGraphIRI.getURI()));
-        reg.put("user2", new SecurityContext("http://test/g1", "http://test/g2", "http://test/g3"));
-        reg.put("user3", new SecurityContext(Quad.defaultGraphIRI.getURI(), "http://test/g2", "http://test/g3"));
-        
-        testdsg1 = DataAccessCtl.controlledDataset(testdsg1, reg);
-        testdsg2 = DataAccessCtl.controlledDataset(testdsg2, reg);
-        testdsg3 = DataAccessCtl.controlledDataset(testdsg3, reg);
-        
-        UserStore userStore = userStore();
-        ConstraintSecurityHandler sh = JettyLib.makeSecurityHandler("*", userStore);
-        JettyLib.addPathConstraint(sh, "/*");
-        
-        fusekiServer = DataAccessCtl.fusekiBuilder(sh,  DataAccessCtl.requestUserServlet)
-            .port(port)
-            .add("data1", testdsg1)
-            .add("data2", testdsg2)
-            .add("data3", testdsg3)
-            .build();
-        fusekiServer.start();
-    }
-
-    @AfterClass public static void afterClass() {
-        fusekiServer.stop();
-    }
-
-    private static UserStore userStore() {
-        PropertyUserStore propertyUserStore = new PropertyUserStore();
-        String[] roles = new String[]{"**"};
-        addUserPassword(propertyUserStore, "userNone", "pwNone", roles);
-        addUserPassword(propertyUserStore, "userDft",  "pwDft",  roles);
-        addUserPassword(propertyUserStore, "user0",    "pw0",    roles);
-        addUserPassword(propertyUserStore, "user1",    "pw1",    roles);
-        addUserPassword(propertyUserStore, "user2",    "pw2",    roles);
-        addUserPassword(propertyUserStore, "user3",    "pw3",    roles);
-        return propertyUserStore;
-    }
-
-    private static void addUserPassword(PropertyUserStore propertyUserStore, String user, String password, String[] roles) {
-        Credential cred  = new Password(password);
-        propertyUserStore.addUser(user, cred, roles);
-    }
-
-    public TestSecurityFilterFuseki(String label, String dsName) {
-        int port = fusekiServer.getPort();
-        baseUrl = "http://localhost:"+port+"/"+dsName;
-    }
-
-    private static String queryAll        = "SELECT * { { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } } }";
-    private static String queryDft        = "SELECT * { ?s ?p ?o }";
-    private static String queryNamed      = "SELECT * { GRAPH ?g { ?s ?p ?o } }";
-
-    private static String queryG2         = "SELECT * { GRAPH <http://test/graph2> { ?s ?p ?o } }";
-    private static String queryGraphNames = "SELECT * { GRAPH ?g { } }";
-
-    private Set<Node> query(String user, String password, String queryString) {
-        Set<Node> results = new HashSet<>();
-        try (RDFConnection conn = RDFConnectionFactory.connectPW(baseUrl, user, password)) {
-            conn.queryResultSet(queryString, rs->{
-                List<QuerySolution> list = Iter.toList(rs);
-                list.stream()
-                    .map(qs->qs.get("s"))
-                    .filter(Objects::nonNull)
-                    .map(RDFNode::asNode)
-                    .forEach(n->results.add(n));
-            });
-        }
-        return results;
-    }
-
-    private void query401(String user, String password, String queryString) {
-        queryHttp(401, user, password, queryString); 
-    }
-
-    private void query403(String user, String password, String queryString) {
-        queryHttp(403, user, password, queryString); 
-    }
-
-    private void queryHttp(int statusCode, String user, String password, String queryString) {
-        try {
-            query(user, password, queryString);
-            if ( statusCode < 200 && statusCode > 299 ) 
-                fail("Should have responded with "+statusCode);
-        } catch (QueryExceptionHTTP ex) {
-            assertEquals(statusCode, ex.getResponseCode());
-        }
-    }
-    
-    @Test public void query_userDft() {
-        Set<Node> results = query("userDft", "pwDft", queryAll);
-        assertSeen(results, s0);
-    }
-
-    @Test public void query_userNone() {
-        Set<Node> results = query("userNone", "pwNone", queryAll);
-        assertSeen(results);
-    }
-
-    @Test public void query_user0() {
-        Set<Node> results = query("user0", "pw0", queryAll);
-        assertSeen(results, s0);
-    }
-    
-    @Test public void query_user1() {
-        Set<Node> results = query("user1", "pw1", queryAll);
-        assertSeen(results, s0, s1);
-    }
-    
-    @Test public void query_bad_user() {
-        query401("userX", "pwX", queryAll);
-    }
-
-    @Test public void query_bad_password() {
-        query401("user0", "not-the-password", queryAll);
-    }
-
-    // Visibility of data.
-    
-    @Test public void query_dyn_1() {
-        Set<Node> results = query("user1", "pw1", "SELECT * FROM <http://test/g1> { ?s ?p ?o }");
-        assertSeen(results, s1);
-    }
-
-    @Test public void query_dyn_2() {
-        Set<Node> results = query("user1", "pw1", "SELECT * FROM <http://test/g2> { ?s ?p ?o }");
-        assertSeen(results);
-    }
-
-    @Test public void query_dyn_3() {
-        Set<Node> results = query("user1", "pw1", "SELECT * FROM <http://test/g1> FROM <http://test/g2> { ?s ?p ?o }");
-        assertSeen(results,s1);
-    }
-    
-    @Test public void query_dyn_4() {
-        Set<Node> results = query("user3", "pw3", "SELECT * FROM <"+Quad.unionGraph.getURI()+"> { ?s ?p ?o }");
-        assertSeen(results, s2, s3);
-        Set<Node> results2 = query("user3", "pw3", "SELECT * { GRAPH <"+Quad.unionGraph.getURI()+"> { ?s ?p ?o } }");
-        assertEquals(results, results2);
-    }
-
-    @Test public void query_dyn_5() {
-        Set<Node> results = query("user3", "pw3", "SELECT * FROM NAMED <http://test/g1> { ?s ?p ?o }");
-        assertSeen(results);
-        Set<Node> results2 = query("user3", "pw3", "SELECT * { GRAPH <http://test/g1> { ?s ?p ?o } }");
-        assertEquals(results, results2);
-    }
-    
-    private Set<Node> gsp(String user, String password, String graphName) {
-        Set<Node> results = new HashSet<>();
-        try (RDFConnection conn = RDFConnectionFactory.connectPW(baseUrl, user, password)) {
-            Model model = graphName == null ? conn.fetch() : conn.fetch(graphName);
-            // Extract subjects.
-            Set<Node> seen = 
-                SetUtils.toSet(
-                    Iter.asStream(model.listSubjects())
-                        .map(r->r.asNode())
-                        );
-            return seen;
-        }
-    }
-
-    private void gsp401(String user, String password, String graphName) {
-        gspHttp(401, user, password, graphName); 
-    }
-    
-    private void gsp403(String user, String password, String graphName) {
-        gspHttp(403, user, password, graphName);
-    }
-
-    private void gsp404(String user, String password, String graphName) {
-        gspHttp(404, user, password, graphName);
-    }
-
-    private void gspHttp(int statusCode, String user, String password, String queryString) {
-        try {
-            gsp(user, password, queryString);
-            if ( statusCode < 200 && statusCode > 299 ) 
-                fail("Should have responded with "+statusCode);
-        } catch (HttpException ex) {
-            assertEquals(statusCode, ex.getResponseCode());
-        }
-    }
-    
-    // When a graph is not visible, it should return 404 except 
-    // for the default graph which should be empty.
-
-    @Test public void gsp_dft_userDft() {
-        Set<Node> results = gsp("userDft", "pwDft", null);
-        assertSeen(results, s0);
-    }
-    
-    @Test public void gsp_dft_userNone() {
-        Set<Node> results = gsp("userNone", "pwNone", null);
-        assertSeen(results);
-    }
-    
-    @Test public void gsp_dft_user0() {
-        Set<Node> results = gsp("user0", "pw0", null);
-        assertSeen(results, s0);
-    }
-
-    @Test public void gsp_dft_user1() {
-        Set<Node> results = gsp("user1", "pw1", null);
-        assertSeen(results, s0);
-    }
-    
-    @Test public void gsp_dft_user2() {
-        Set<Node> results = gsp("user2", "pw2", null);
-        assertSeen(results);
-    }
-    
-    @Test public void gsp_graph1_userDft() {
-        gsp404("userDft", "pwDft", "http://test/g1");
-    }
-    
-    @Test public void gsp_graph1_userNone() {
-        gsp404("userNone", "pwNone", "http://test/g1");
-    }
-    
-    @Test public void gsp_graph1_user0() {
-        gsp404("user0", "pw0", "http://test/g1");
-    }
-
-    @Test public void gsp_graph1_user1() {
-        Set<Node> results = gsp("user1", "pw1", "http://test/g1");
-        assertSeen(results, s1);
-    }
-    
-    @Test public void gsp_graph1_user2() {
-        gsp404("user2", "pw2", "http://test/g1");
-    }
-    
-    // No such graph.
-    @Test public void gsp_graphX_userDft() {
-        gsp404("userDft", "pwDft", "http://test/gX");
-    }
-    
-    @Test public void gsp_graphX_userNone() {
-        gsp404("userNone", "pwNone", "http://test/gX");
-    }
-    
-    @Test public void gsp_graphX_user0() {
-        gsp404("user0", "pw0", "http://test/gX");
-    }
-
-    @Test public void gsp_graphX_user1() {
-        gsp404("user1", "pw1", "http://test/g1X");
-    }
-    
-    @Test public void gsp_graphX_user2() {
-        gsp404("user2", "pw2", "http://test/gX");
-    }
-    
-    @Test public void gsp_bad_user() {
-        gsp401("userX", "pwX", null);
-    }
-
-    @Test public void gsp_bad_password() {
-        gsp401("user0", "not-the-password", null);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/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 ac0bd0f..b9cbe82 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
@@ -18,7 +18,6 @@
 
 package org.apache.jena.fuseki.access;
 
-import static org.apache.jena.fuseki.access.AccessTestLib.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -34,6 +33,10 @@ import java.util.stream.Stream;
 import org.apache.jena.atlas.iterator.Iter;
 import org.apache.jena.atlas.lib.Creator;
 import org.apache.jena.atlas.lib.SetUtils;
+import org.apache.jena.atlas.lib.StrUtils;
+import org.apache.jena.fuseki.access.DataAccessCtl;
+import org.apache.jena.fuseki.access.SecurityContext;
+import org.apache.jena.fuseki.access.SecurityRegistry;
 import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.query.Dataset;
@@ -44,9 +47,12 @@ import org.apache.jena.query.QuerySolution;
 import org.apache.jena.rdf.model.Model;
 import org.apache.jena.rdf.model.ModelFactory;
 import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFParser;
 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.sse.SSE;
 import org.apache.jena.system.Txn;
 import org.apache.jena.tdb.TDB;
 import org.apache.jena.tdb.TDBFactory;
@@ -92,22 +98,17 @@ public class TestSecurityFilterLocal {
     
     public TestSecurityFilterLocal(String name, Creator<DatasetGraph> source, boolean applyFilterTDB) {
         DatasetGraph dsgBase = source.create();
-        AccessTestLib.addTestData(dsgBase);
+        addTestData(dsgBase);
         reg.put("userNone", SecurityContext.NONE);
-        reg.put("userDft", SecurityContext.DFT_GRAPH);
-        reg.put("user0", new SecurityContext(Quad.defaultGraphIRI.getURI()));
-        reg.put("user1", new SecurityContext("http://test/g1", Quad.defaultGraphIRI.getURI()));
-        reg.put("user2", new SecurityContext("http://test/g1", "http://test/g2", "http://test/g3"));
+        reg.put("userDft", SecurityContextView.DFT_GRAPH);
+        reg.put("user0", new SecurityContextView(Quad.defaultGraphIRI.getURI()));
+        reg.put("user1", new SecurityContextView("http://test/g1", Quad.defaultGraphIRI.getURI()));
+        reg.put("user2", new SecurityContextView("http://test/g1", "http://test/g2", "http://test/g3"));
         testdsg = DataAccessCtl.controlledDataset(dsgBase, reg);
         this.applyFilterTDB = applyFilterTDB;
         this.applyFilterDSG = ! applyFilterTDB;
     }
     
-    private static void assertSeen(Set<Node> visible, Node ... expected) {
-        Set<Node> expectedNodes = new HashSet<>(Arrays.asList(expected));
-        assertEquals(expectedNodes, visible);
-    }
-
     private static String queryAll        = "SELECT * { { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } } }";
     private static String queryDft        = "SELECT * { ?s ?p ?o }";
     private static String queryNamed      = "SELECT * { GRAPH ?g { ?s ?p ?o } }";
@@ -124,7 +125,7 @@ public class TestSecurityFilterLocal {
             Txn.calculateRead(ds, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryString, ds)) {
                     if ( applyFilterTDB )
-                        sCxt.filterTDB(dsg1, qExec);
+                        ((SecurityContextView)sCxt).filterTDB(dsg1, qExec);
                     List<QuerySolution> results = Iter.toList(qExec.execSelect());
                     Stream<Node> stream = results.stream()
                         .map(qs->qs.get("s"))
@@ -145,7 +146,7 @@ public class TestSecurityFilterLocal {
             Txn.calculateRead(testdsg, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryString, model)) {
                     if ( applyFilterTDB )
-                        sCxt.filterTDB(dsg1, qExec);
+                        ((SecurityContextView)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);
                     return SetUtils.toSet(stream);
@@ -162,7 +163,7 @@ public class TestSecurityFilterLocal {
             Txn.calculateRead(ds, ()->{
                 try(QueryExecution qExec = QueryExecutionFactory.create(queryGraphNames, ds)) {
                     if ( applyFilterTDB )
-                        sCxt.filterTDB(dsg1, qExec);
+                        ((SecurityContextView)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);
                     return SetUtils.toSet(stream);
@@ -352,4 +353,37 @@ public class TestSecurityFilterLocal {
         Set<Node> visible = subjects(dsg, graphChoice, queryDft, sCxt);
         assertSeen(visible, expected);
     }
+    
+    private static String dataStr = StrUtils.strjoinNL 
+        ("PREFIX : <http://test/>"
+            ,""
+            ,":s0 :p 0 ."
+            ,":g1 { :s1 :p 1 }"
+            ,":g2 { :s2 :p 2 }"
+            ,":g3 { :s3 :p 3 }"
+            ,":g4 { :s4 :p 4 }"
+            );
+
+
+    public static Node s0 = SSE.parseNode("<http://test/s0>"); 
+    public static Node s1 = SSE.parseNode("<http://test/s1>"); 
+    public static Node s2 = SSE.parseNode("<http://test/s2>"); 
+    public static Node s3 = SSE.parseNode("<http://test/s3>"); 
+    public static Node s4 = SSE.parseNode("<http://test/s4>"); 
+
+    public static Node g1 = SSE.parseNode("<http://test/g1>"); 
+    public static Node g2 = SSE.parseNode("<http://test/g2>"); 
+    public static Node g3 = SSE.parseNode("<http://test/g3>"); 
+    public static Node g4 = SSE.parseNode("<http://test/g4>"); 
+
+    public static void addTestData(DatasetGraph dsg) {
+        Txn.executeWrite(dsg, ()->{
+            RDFParser.create().fromString(dataStr).lang(Lang.TRIG).parse(dsg);
+        });
+    }
+    
+    public static void assertSeen(Set<Node> visible, Node ... expected) {
+        Set<Node> expectedNodes = new HashSet<>(Arrays.asList(expected));
+        assertEquals(expectedNodes, visible);
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestServiceRegistry.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestServiceRegistry.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestServiceRegistry.java
new file mode 100644
index 0000000..ffd12e8
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestServiceRegistry.java
@@ -0,0 +1,40 @@
+/*
+ * 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.jena.fuseki.access;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.jena.sparql.core.assembler.AssemblerUtils;
+import org.apache.jena.sys.JenaSystem;
+import org.junit.Test;
+
+/** Test parsing of assemblers with security aspects */ 
+public class TestServiceRegistry {
+    static { JenaSystem.init(); }
+    static final String DIR = "testing/SecurityRegistry/";
+
+    @Test public void assemblerFile() { 
+        AuthorizationService authService = (AuthorizationService)AssemblerUtils.build(DIR+"assem-security-registry.ttl", VocabSecurity.tSecurityRegistry);
+        assertNotNull(authService);
+        SecurityRegistry sReg = (SecurityRegistry)authService;
+        assertEquals(4, sReg.keys().size());
+        assertEquals(3, sReg.get("user1").visibleGraphs().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/testing/Access/allowedUsers.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/testing/Access/allowedUsers.ttl b/jena-fuseki2/jena-fuseki-access/testing/Access/allowedUsers.ttl
deleted file mode 100644
index d674a64..0000000
--- a/jena-fuseki2/jena-fuseki-access/testing/Access/allowedUsers.ttl
+++ /dev/null
@@ -1,15 +0,0 @@
-PREFIX :        <http://example/>
-PREFIX fuseki:  <http://jena.apache.org/fuseki#>
-PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
-PREFIX tdb2:    <http://jena.apache.org/2016/tdb#>
-PREFIX ja:      <http://jena.hpl.hp.com/2005/11/Assembler#>
-PREFIX access:  <http://jena.apache.org/access#>
-
-:none :p 123 .
-
-:r1 fuseki:allowedUsers "user1" ,"user2" .
-:r2 fuseki:allowedUsers ( "user1" "user2" ) .
-
-:rLoggedIn fuseki:allowedUsers "*" .
-

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security-shared.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security-shared.ttl b/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security-shared.ttl
deleted file mode 100644
index 5372c81..0000000
--- a/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security-shared.ttl
+++ /dev/null
@@ -1,58 +0,0 @@
-PREFIX :        <#>
-PREFIX fuseki:  <http://jena.apache.org/fuseki#>
-PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
-PREFIX tdb2:    <http://jena.apache.org/2016/tdb#>
-PREFIX ja:      <http://jena.hpl.hp.com/2005/11/Assembler#>
-PREFIX access:  <http://jena.apache.org/access#>
-
-[] rdf:type fuseki:Server ;
-   fuseki:services (
-     <#service_tdb2>
-     <#service_plain>
-   ) .
-
-<#service_tdb2> rdf:type fuseki:Service ;
-    rdfs:label                      "Access controlled dataset" ;
-    fuseki:name                     "database" ;
-    ## Read-only operations.
-    fuseki:serviceQuery             "query" ;
-    fuseki:serviceQuery             "sparql" ;
-    fuseki:serviceReadGraphStore    "get" ;
-    fuseki:dataset                  <#access_dataset>;
-    .
-
-## Dataset 1
-## Access control
-<#access_dataset>  rdf:type access:AccessControlledDataset ;
-    access:registry   <#securityRegistry> ;
-    access:dataset    <#tdb_dataset_shared> ;
-    .
-
-<#securityRegistry> rdf:type access:SecurityRegistry ;
-    access:entry ("user1" <http://host/graphname1>  <http://host/graphname2> ) ;
-    access:entry ("user1" <http://host/graphname3> ) ;
-    access:entry ("user2" <http://host/graphname9> ) ;
-    access:entry [ access:user "user3" ; access:graphs (<http://host/graphname3> <http://host/graphname4> ) ] ;
-    access:entry [ access:user "user3" ; access:graphs <http://host/graphname5> ] ;
-    access:entry [ access:user "userZ" ; access:graphs <http://host/graphnameZ> ] ;
-    .
-## Dataset 2
-## No data access control.
-<#service_plain> rdf:type fuseki:Service ;
-    fuseki:name                  "plain";
-    fuseki:serviceQuery          "query";
-    fuseki:serviceQuery          "sparql";
-    fuseki:serviceUpdate         "update";
-    fuseki:serviceUpload         "upload" ;
-    fuseki:serviceReadGraphStore "data" ;
-    fuseki:serviceReadGraphStore "get" ;
-    fuseki:dataset <#tdb_dataset_shared> ;
-    .
-
-## Shared database.
-<#tdb_dataset_shared> rdf:type      tdb2:DatasetTDB2 ;
-    tdb2:location "--mem--/DB" ;
-    tdb2:unionDefaultGraph true ;
-    .
-

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security.ttl b/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security.ttl
deleted file mode 100644
index 8506be3..0000000
--- a/jena-fuseki2/jena-fuseki-access/testing/Access/assem-security.ttl
+++ /dev/null
@@ -1,63 +0,0 @@
-PREFIX :        <#>
-PREFIX fuseki:  <http://jena.apache.org/fuseki#>
-PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
-PREFIX tdb2:    <http://jena.apache.org/2016/tdb#>
-PREFIX ja:      <http://jena.hpl.hp.com/2005/11/Assembler#>
-PREFIX access:  <http://jena.apache.org/access#>
-
-[] rdf:type fuseki:Server ;
-   fuseki:services (
-     <#service_tdb2>
-     <#service_plain>
-   ) .
-
-<#service_tdb2> rdf:type fuseki:Service ;
-    rdfs:label                      "Access controlled dataset" ;
-    fuseki:name                     "database" ;
-    ## Read-only operations.
-    fuseki:serviceQuery             "query" ;
-    fuseki:serviceQuery             "sparql" ;
-    fuseki:serviceReadGraphStore    "get" ;
-    fuseki:dataset                  <#access_dataset>;
-    .
-
-## Dataset 1
-## Access control
-<#access_dataset>  rdf:type access:AccessControlledDataset ;
-    access:registry   <#securityRegistry> ;
-    access:dataset    <#tdb_dataset_read> ;
-    .
-
-## Own database
-<#tdb_dataset_read> rdf:type      tdb2:DatasetTDB2 ;
-    tdb2:location "--mem--" ;
-    tdb2:unionDefaultGraph true ;
-    .
-
-<#securityRegistry> rdf:type access:SecurityRegistry ;
-    access:entry ("user1" <http://host/graphname1>  <http://host/graphname2> ) ;
-    access:entry ("user1" <http://host/graphname3> ) ;
-    access:entry ("user2" <http://host/graphname9> ) ;
-    access:entry [ access:user "user3" ; access:graphs (<http://host/graphname3> <http://host/graphname4> ) ] ;
-    access:entry [ access:user "user3" ; access:graphs <http://host/graphname5> ] ;
-    access:entry [ access:user "userZ" ; access:graphs <http://host/graphnameZ> ] ;
-    .
-
-## Dataset 2
-## No data access control.
-<#service_plain> rdf:type fuseki:Service ;
-    fuseki:name                  "plain";
-    fuseki:serviceQuery          "query";
-    fuseki:serviceQuery          "sparql";
-    fuseki:serviceUpdate         "update";
-    fuseki:serviceUpload         "upload" ;
-    fuseki:serviceReadWriteGraphStore "data" ;
-    fuseki:serviceReadGraphStore "get" ;
-    fuseki:dataset <#tdb_dataset> ;
-    .
-    
-<#tdb_dataset> rdf:type      tdb2:DatasetTDB2 ;
-    tdb2:location "--mem--" ;
-    .
-    
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/2f1fefbd/jena-fuseki2/jena-fuseki-access/testing/Access/config-server-1.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/testing/Access/config-server-1.ttl b/jena-fuseki2/jena-fuseki-access/testing/Access/config-server-1.ttl
deleted file mode 100644
index ce42505..0000000
--- a/jena-fuseki2/jena-fuseki-access/testing/Access/config-server-1.ttl
+++ /dev/null
@@ -1,43 +0,0 @@
-PREFIX :        <#>
-PREFIX fuseki:  <http://jena.apache.org/fuseki#>
-PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
-PREFIX tdb2:    <http://jena.apache.org/2016/tdb#>
-PREFIX ja:      <http://jena.hpl.hp.com/2005/11/Assembler#>
-PREFIX access:  <http://jena.apache.org/access#>
-
-[] rdf:type fuseki:Server ;
-   fuseki:allowedUsers  "*";
-   fuseki:services (
-     <#service_tdb2>
-     <#service_plain>
-   ) .
-
-<#service_tdb2> rdf:type fuseki:Service ;
-    rdfs:label                      "Access controlled dataset" ;
-    fuseki:allowedUsers             "user1", "user3";
-    fuseki:name                     "database1" ;
-    fuseki:serviceQuery             "query" ;
-    fuseki:serviceQuery             "sparql" ;
-    fuseki:serviceReadGraphStore    "get" ;
-    fuseki:dataset                  <#dataset1>;
-    .
-
-## Own database
-<#dataset1> rdf:type  ja:MemoryDataset ;
-    .
-
-## Dataset 2
-## No service
-<#service_plain> rdf:type fuseki:Service ;
-    fuseki:name                  "database2";
-    fuseki:serviceQuery          "query";
-    fuseki:serviceQuery          "sparql";
-    fuseki:serviceReadGraphStore "get" ;
-    fuseki:dataset <#tdb_dataset> ;
-    .
-    
-<#tdb_dataset> rdf:type      tdb2:DatasetTDB2 ;
-    tdb2:location "--mem--" ;
-    .
-    
\ No newline at end of file