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