You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2015/01/13 21:03:43 UTC
jena git commit: Changes to implement JENA-847 Added
SecurityEvaluatorAssembler. Extracted AssemblerConstants from
SecuredAssembler Added SecurityEvaluatorAssembler testing to
SecuredAssemblerTest
Repository: jena
Updated Branches:
refs/heads/master 7e256560e -> d1b5e21df
Changes to implement JENA-847
Added SecurityEvaluatorAssembler.
Extracted AssemblerConstants from SecuredAssembler
Added SecurityEvaluatorAssembler testing to SecuredAssemblerTest
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/d1b5e21d
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/d1b5e21d
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/d1b5e21d
Branch: refs/heads/master
Commit: d1b5e21dfdb3f83ee6855df9c92b9db54690b3c5
Parents: 7e25656
Author: claude <cl...@xenei.com>
Authored: Tue Jan 13 19:56:10 2015 +0000
Committer: claude <cl...@xenei.com>
Committed: Tue Jan 13 19:56:10 2015 +0000
----------------------------------------------------------------------
.../jena/security/AssemblerConstants.java | 44 +++++
.../apache/jena/security/SecuredAssembler.java | 157 +++++++++++-----
.../security/SecurityEvaluatorAssembler.java | 186 +++++++++++++++++++
.../jena/security/SecuredAssemblerTest.java | 17 ++
.../jena/security/SecuredAssemblerTest.ttl | 20 ++
5 files changed, 382 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/d1b5e21d/jena-security/src/main/java/org/apache/jena/security/AssemblerConstants.java
----------------------------------------------------------------------
diff --git a/jena-security/src/main/java/org/apache/jena/security/AssemblerConstants.java b/jena-security/src/main/java/org/apache/jena/security/AssemblerConstants.java
new file mode 100644
index 0000000..43c2034
--- /dev/null
+++ b/jena-security/src/main/java/org/apache/jena/security/AssemblerConstants.java
@@ -0,0 +1,44 @@
+package org.apache.jena.security;
+
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.ResourceFactory;
+
+public interface AssemblerConstants {
+ public static final String URI = "http://apache.org/jena/security/Assembler#";
+ /**
+ * Property named URI+"evaluatorFactory"
+ */
+ public static final Property EVALUATOR_FACTORY =
+ ResourceFactory.createProperty( URI + "evaluatorFactory" );
+ /**
+ * Property named URI+"Model"
+ */
+ public static final Property SECURED_MODEL = ResourceFactory.createProperty( URI + "Model" );
+ /**
+ * Property named URI+"baseModel"
+ */
+ public static final Property BASE_MODEL = ResourceFactory.createProperty( URI + "baseModel" );
+ /**
+ * Property named URI+"Evaluator"
+ */
+ public static final Property EVALUATOR_ASSEMBLER = ResourceFactory.createProperty( URI+"Evaluator" );
+ /**
+ * Property named URI+"evaluatorImpl"
+ */
+ public static final Property EVALUATOR_IMPL =
+ ResourceFactory.createProperty( URI + "evaluatorImpl" );
+
+ /**
+ * Property named URI+"evaluatorClass"
+ */
+ public static final Property EVALUATOR_CLASS =
+ ResourceFactory.createProperty( URI + "evaluatorClass" );
+ /**
+ * Property named URI+"evaluatorImpl"
+ */
+ public static final Property ARGUMENT_LIST =
+ ResourceFactory.createProperty( URI + "args" );
+
+ // message formats
+ public static final String NO_X_PROVIDED = "No %s provided for %s";
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/d1b5e21d/jena-security/src/main/java/org/apache/jena/security/SecuredAssembler.java
----------------------------------------------------------------------
diff --git a/jena-security/src/main/java/org/apache/jena/security/SecuredAssembler.java b/jena-security/src/main/java/org/apache/jena/security/SecuredAssembler.java
index 04964dc..f3a9716 100644
--- a/jena-security/src/main/java/org/apache/jena/security/SecuredAssembler.java
+++ b/jena-security/src/main/java/org/apache/jena/security/SecuredAssembler.java
@@ -25,10 +25,9 @@ import com.hp.hpl.jena.assembler.assemblers.ModelAssembler;
import com.hp.hpl.jena.assembler.exceptions.AssemblerException;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
-import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
-import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.sparql.util.MappingRegistry;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -42,52 +41,97 @@ import java.lang.reflect.Modifier;
* <>; ja:loadClass "org.apache.jena.security.SecuredAssembler" .
*
* sec:Model rdfs:subClassOf ja:NamedModel .
+ *
+ * sec:evaluator rdfs:domain sec:Model ;
+ * rdfs:range sec:Evaluator .
* </pre></code>
*
* The model definition should include something like.
*
* <code><pre>
- * [] a ja:Model ;
- * sec:baseModel jena_model ;
- * ja:modelName "modelName";
- * sec:evaluatorFactory "javaclass";
+ * my:secModel a sec:Model ;
+ * sec:baseModel my:baseModel ;
+ * ja:modelName "http://example.com/securedModel" ;
+ * sec:evaluatorFactory "org.apache.jena.security.MockSecurityEvaluator" ;
* .
* </pre></code>
*
* Terms used in above example:
+ *
* <dl>
- * <dt>
- * jena_model</dt><dd>Another model defined in the assembler file.
- * </dd><dt>
- * "modelName"</dt><dd>The name of the model as identified in the security manager
- * </dd><dt>
- * "javaclass"</dt><dd>The name of a java class that implements a Evaluator Factory. The Factory must have
- * static method <code>getInstance()</code> that returns a SecurityEvaluator.
+ * <dt>my:secModel</dt>
+ * <dd>The secured model as referenced in the assembler file.</dd>
+ *
+ * <dt>sec:Model</dt>
+ * <dd>Identifes my:secModel as a secured model</dd>
+ *
+ * <dt>sec:baseModel</dt>
+ * <dd>Identifies my:baseModel as the base model we are applying security to</dd>
+ *
+ * <dt>my:baseModel</dt>
+ * <dd>a ja:Model (or subclass) defined elsewhere in the assembler file</dd>
+ *
+ * <dt>ja:modelName</dt>
+ * <dd>The name of the graph as it will be addressed in the security environment
+ * (see ja:NamedModel examples from Jena)</dd>
+ *
+ * <dt>sec:evaluatorFactory</dt>
+ * <dd>Identifies "org.apache.jena.security.MockSecurityEvaluator" as the java class
+ * that implements an Evaluator Factory. The Factory must have
+ * static method <code>getInstance()</code> that returns a SecurityEvaluator.</dd>
+ * </dl>
+ *
+ * or if using an evaluator assembler
+ *
+ * <code><pre>
+ * my:secModel a sec:Model ;
+ * sec:baseModel my:baseModel ;
+ * ja:modelName "http://example.com/securedModel" ;
+ * sec:evaluatorImpl ex:myEvaluator;
+ * .
+ *
+ * ex:myEvaluator a sec:Evaluator ;
+ * ex:arg1 "argument 1 for my evaluator constructor" ;
+ * ex:arg2 "argument 2 for my evaluator constructor" ;
+ * .
+ *
+ * </pre></code>
+ *
+ * Terms used in above example:
+ *
+ * <dl>
+ * <dt>my:secModel</dt>
+ * <dd>The secured model as referenced in the assembler file.</dd>
+ *
+ * <dt>sec:Model</dt>
+ * <dd>Identifes my:secModel as a secured model</dd>
+ *
+ * <dt>sec:baseModel</dt>
+ * <dd>Identifies my:baseModel as the base model we are applying security to</dd>
+ *
+ * <dt>my:baseModel</dt>
+ * <dd>a ja:Model (or subclass) defined elsewhere in the assembler file</dd>
+ *
+ * <dt>ja:modelName</dt>
+ * <dd>The name of the graph as it will be addressed in the security environment
+ * (see ja:NamedModel examples from Jena)</dd>
+ *
+ * <dt>sec:evaluatorImpl</dt>
+ * <dd>Identifies ex:myEvaluator as a SecurityEvaluator defined elsewhere in the assembler file.
+ * It must subclass as a sec:Evaluator.</dd>
* </dd>
+ *
+ * <dt>ex:arg1 and ex:arg2</dt>
+ * <dd>Arguments as defined by the user defined security evaluator assembler.</dd>
* </dl>
+
* </p>
*
*/
-public class SecuredAssembler extends ModelAssembler {
+public class SecuredAssembler extends ModelAssembler implements AssemblerConstants {
private static boolean initialized;
- public static final String URI = "http://apache.org/jena/security/Assembler#";
- /**
- * Property named URI+"evaluatorFactory"
- */
- public static final Property EVALUATOR_FACTORY =
- ResourceFactory.createProperty( URI + "evaluatorFactory" );
- /**
- * Property named URI+"Model"
- */
- public static final Property SECURED_MODEL = ResourceFactory.createProperty( URI + "Model" );
- /**
- * Property named URI+"baseModel"
- */
- public static final Property BASE_MODEL = ResourceFactory.createProperty( URI + "baseModel" );
-
// message formats
- private static final String NO_X_PROVIDED = "No %s provided for %s";
private static final String ERROR_FINDING_FACTORY = "Error finding factory class %s: %s";
static { init() ; }
@@ -115,6 +159,7 @@ public class SecuredAssembler extends ModelAssembler {
if ( group == null )
group = Assembler.general ;
group.implementWith( SECURED_MODEL, new SecuredAssembler()) ;
+ group.implementWith( EVALUATOR_ASSEMBLER, new SecurityEvaluatorAssembler());
}
@Override
@@ -125,7 +170,7 @@ public class SecuredAssembler extends ModelAssembler {
{
throw new AssemblerException( root, String.format( NO_X_PROVIDED, BASE_MODEL, root ));
}
- Model baseModel = a.openModel(rootModel, mode);
+ Model baseModel = a.openModel(rootModel, Mode.ANY);
Literal modelName = getUniqueLiteral( root, JA.modelName );
if (modelName == null)
@@ -134,11 +179,38 @@ public class SecuredAssembler extends ModelAssembler {
}
Literal factoryName = getUniqueLiteral( root, EVALUATOR_FACTORY );
- if (factoryName == null)
+ Resource evaluatorImpl = getUniqueResource( root, EVALUATOR_IMPL );
+ if (factoryName == null && evaluatorImpl == null)
+ {
+ throw new AssemblerException( root,
+ String.format( "Either a %s or a %s must be provided for %s" ,
+ EVALUATOR_FACTORY, EVALUATOR_IMPL, root ));
+ }
+ if (factoryName != null && evaluatorImpl != null)
{
- throw new AssemblerException( root, String.format( NO_X_PROVIDED, EVALUATOR_FACTORY, root ));
+ throw new AssemblerException( root,
+ String.format( "May not specify both a %s and a %s for %s" ,
+ EVALUATOR_FACTORY, EVALUATOR_IMPL, root ));
}
SecurityEvaluator securityEvaluator = null;
+ if (factoryName != null)
+ {
+ securityEvaluator = executeEvaluatorFactory( root, factoryName );
+ }
+ if (evaluatorImpl != null)
+ {
+ securityEvaluator = getEvaluatorImpl( a, evaluatorImpl );
+ }
+ return Factory.getInstance(securityEvaluator, modelName.asLiteral().getString(), baseModel);
+
+ }
+
+ @Override
+ protected Model openEmptyModel(Assembler a, Resource root, Mode mode) {
+ return open(a, root, mode);
+ }
+
+ private SecurityEvaluator executeEvaluatorFactory(Resource root, Literal factoryName ) {
try
{
Class<?> factoryClass = Class.forName( factoryName.getString() );
@@ -151,7 +223,7 @@ public class SecuredAssembler extends ModelAssembler {
{
throw new AssemblerException( root, String.format( "%s (found at %s for %s) getInstance() must be a static method", factoryName, EVALUATOR_FACTORY, root ));
}
- securityEvaluator = (SecurityEvaluator) method.invoke( null );
+ return (SecurityEvaluator) method.invoke( null );
}
catch (SecurityException e)
{
@@ -177,15 +249,16 @@ public class SecuredAssembler extends ModelAssembler {
{
throw new AssemblerException( root, String.format( ERROR_FINDING_FACTORY, factoryName, e.getMessage() ), e);
}
-
- return Factory.getInstance(securityEvaluator, modelName.asLiteral().getString(), baseModel);
-
}
-
- @Override
- protected Model openEmptyModel(Assembler a, Resource root, Mode mode) {
- return open(a, root, mode);
+
+ private SecurityEvaluator getEvaluatorImpl(Assembler a, Resource evaluatorImpl ) {
+ Object obj = a.open(a, evaluatorImpl, Mode.ANY);
+ if (obj instanceof SecurityEvaluator)
+ {
+ return (SecurityEvaluator) obj;
+ }
+ throw new AssemblerException( evaluatorImpl, String.format(
+ "%s does not specify a SecurityEvaluator instance", evaluatorImpl));
}
-
}
http://git-wip-us.apache.org/repos/asf/jena/blob/d1b5e21d/jena-security/src/main/java/org/apache/jena/security/SecurityEvaluatorAssembler.java
----------------------------------------------------------------------
diff --git a/jena-security/src/main/java/org/apache/jena/security/SecurityEvaluatorAssembler.java b/jena-security/src/main/java/org/apache/jena/security/SecurityEvaluatorAssembler.java
new file mode 100644
index 0000000..0669c5d
--- /dev/null
+++ b/jena-security/src/main/java/org/apache/jena/security/SecurityEvaluatorAssembler.java
@@ -0,0 +1,186 @@
+/*
+ * 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.security;
+
+import com.hp.hpl.jena.assembler.Assembler;
+import com.hp.hpl.jena.assembler.Mode;
+import com.hp.hpl.jena.assembler.assemblers.AssemblerBase;
+import com.hp.hpl.jena.assembler.exceptions.AssemblerException;
+import com.hp.hpl.jena.rdf.model.Literal;
+import com.hp.hpl.jena.rdf.model.NodeIterator;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.Seq;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A simple assembler for a SecurityEvaluator
+ * <p>
+ * This assembler load the specified class, locates the first constructor that accepts
+ * the number of arguments in the assembler file, and calls it passing the arguments.
+ * Generally the result of this assembler is passed to a sec:Model construction.
+ * @see SecuredAssembler
+ * </p>
+ * <ul>
+ * <li>The evaluator must have one and only one public constructor
+ * that takes the number of arguments specified in the assembler file.
+ * </li>
+ *
+ * <li>
+ * The evaluator may have more constructors but they may not have the same
+ * number of arguments as specified in the assembler file.
+ * </li>
+ *
+ * <li>
+ * The arguments must be specified in the assembler file in the order that they
+ * should be passed to the constructor.
+ * </li>
+ * </ul>
+ *
+ * <p>
+ * Literal arguments are converted to their data type before calling the constructor. For example
+ * "13"^^xsd:int will be converted to an Integer with the value of 13.
+ * </p>
+ * The assembler file should include the following
+ * <code><pre>
+ * @prefix xsd: <http://www.w3.org/2001/XMLSchema#>
+ *
+ * <>; ja:loadClass "org.apache.jena.security.SecuredAssembler" .
+ *
+ * sec:Model rdfs:subClassOf ja:NamedModel .
+ *
+ * </pre></code>
+ *
+ * The model definition should include something like.
+ *
+ * <code><pre>
+ * ex:myEvaluator a sec:Evaluator ;
+ * sec:args [ rdf:_1 "argument 1 for my evaluator constructor" ;
+ * rdf:_2 "13"^^xsd:int ; ];
+ * sec:evaluatorClass "evaluatorClassname";
+ * .
+ * </pre></code>
+ *
+ * Terms used in above example:
+ *
+ * <dl>
+ * <dt>my:secEvaluator</dt>
+ * <dd>The security evaluator as referenced in the assembler file.</dd>
+ *
+ * <dt>sec:Evaluator</dt>
+ * <dd>Identifies my:secEvaluator as a SecurityEvaluator</dd>
+ *
+ * <dt>sec:args</dt>
+ * <dd>Identifies the argument list</dd>
+ *
+ * <dt>rdf:_1</dt>
+ * <dd>The first argument</dd>
+ *
+ * <dt>rdf:_2</dt>
+ * <dd>The second argument (an integer in this case</dd>
+ *
+ * <dt>sec:evaluatorClass</dt>
+ * <dd>The fully qualified name of the SecurityEvaluator class to call. This class must extend
+ * SecurityEvaluator, and must have one and only one constructor that takes the number of arguments
+ * specified in sec:args</dd>
+ *
+ * </p>
+ *
+ */
+public class SecurityEvaluatorAssembler extends AssemblerBase implements Assembler, AssemblerConstants {
+ // initialization and registration is performed by SecuredAssembler
+
+ @Override
+ public SecurityEvaluator open(Assembler a, Resource root, Mode mode) {
+
+ Literal className = getUniqueLiteral( root, EVALUATOR_CLASS );
+ if (className == null)
+ {
+ throw new AssemblerException( root, String.format( NO_X_PROVIDED, EVALUATOR_CLASS, root ));
+ }
+
+ Class<?> clazz;
+ try {
+ clazz = Class.forName(className.getString());
+ } catch (ClassNotFoundException e1) {
+ throw new AssemblerException( root, String.format( "Can not locate class %s as specified by %s in %s", className, EVALUATOR_CLASS, root ));
+ }
+ if ( ! SecurityEvaluator.class.isAssignableFrom( clazz ))
+ {
+ throw new AssemblerException( root, String.format( "Class %s as specified by %s in %s does not implement SecurityEvaluator", className, EVALUATOR_CLASS, root ));
+ }
+
+ // get the arguments as specified.
+ List<Object> args = new ArrayList<Object>();
+ Resource argRes = getUniqueResource( root, ARGUMENT_LIST );
+ if (argRes != null)
+ {
+ Seq seq = argRes.as( Seq.class );
+ NodeIterator iter = seq.iterator();
+ RDFNode n = null;
+ while (iter.hasNext())
+ {
+ n = iter.next();
+ if (n.isLiteral())
+ {
+ args.add( n.asLiteral().getValue());
+ }
+ else if (n.isResource())
+ {
+ a.open( a, n.asResource(), mode );
+ }
+ else
+ {
+ throw new AssemblerException( root, String.format( "%s must be a literal or a resource", n ));
+ }
+ }
+ }
+
+ for (Constructor<?> c : clazz.getConstructors())
+ {
+ if (c.getParameterTypes().length == args.size())
+ {
+ try {
+ if (args.size() == 0)
+ {
+ return (SecurityEvaluator) c.newInstance();
+ }
+ else
+ {
+ return (SecurityEvaluator) c.newInstance( args.toArray() );
+ }
+ } catch (InstantiationException e) {
+ throw new AssemblerException( root, e.getMessage(), e );
+ } catch (IllegalAccessException e) {
+ throw new AssemblerException( root, e.getMessage(), e );
+ } catch (IllegalArgumentException e) {
+ throw new AssemblerException( root, e.getMessage(), e );
+ } catch (InvocationTargetException e) {
+ throw new AssemblerException( root, e.getMessage(), e );
+ }
+ }
+
+ }
+ throw new AssemblerException( root, String.format( "Class %s does not have a %s argument constructor", className, args.size() ));
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/d1b5e21d/jena-security/src/test/java/org/apache/jena/security/SecuredAssemblerTest.java
----------------------------------------------------------------------
diff --git a/jena-security/src/test/java/org/apache/jena/security/SecuredAssemblerTest.java b/jena-security/src/test/java/org/apache/jena/security/SecuredAssemblerTest.java
index c53ac78..ed5a265 100644
--- a/jena-security/src/test/java/org/apache/jena/security/SecuredAssemblerTest.java
+++ b/jena-security/src/test/java/org/apache/jena/security/SecuredAssemblerTest.java
@@ -57,4 +57,21 @@ public class SecuredAssemblerTest
Assert.assertTrue( o instanceof SecuredModel );
}
+ @Test
+ public void testCreationWithArgs() throws Exception {
+
+ Resource r = model.createResource( "http://apache.org/jena/security/test#secModel2");
+ Object o = assembler.open( r );
+ Assert.assertTrue( o instanceof Model);
+ Assert.assertTrue( o instanceof SecuredModel );
+ }
+
+ @Test
+ public void testSecurityEvaluatorWithArgs() throws Exception {
+
+ Resource r = model.createResource( "http://apache.org/jena/security/test#secEvaluator");
+ Object o = assembler.open( r );
+ Assert.assertTrue( o instanceof SecurityEvaluator );
+ Assert.assertTrue( o instanceof MockSecurityEvaluator );
+ }
}
http://git-wip-us.apache.org/repos/asf/jena/blob/d1b5e21d/jena-security/src/test/resources/org/apache/jena/security/SecuredAssemblerTest.ttl
----------------------------------------------------------------------
diff --git a/jena-security/src/test/resources/org/apache/jena/security/SecuredAssemblerTest.ttl b/jena-security/src/test/resources/org/apache/jena/security/SecuredAssemblerTest.ttl
index 711cfec..60ac5bb 100644
--- a/jena-security/src/test/resources/org/apache/jena/security/SecuredAssemblerTest.ttl
+++ b/jena-security/src/test/resources/org/apache/jena/security/SecuredAssemblerTest.ttl
@@ -5,6 +5,7 @@
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix sec: <http://apache.org/jena/security/Assembler#> .
@prefix my: <http://apache.org/jena/security/test#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#>
<> ja:loadClass "org.apache.jena.security.SecuredAssembler" .
@@ -23,3 +24,22 @@ my:secModel
sec:evaluatorFactory "org.apache.jena.security.MockSecurityEvaluator" ;
.
+my:secModel2
+ a sec:Model;
+ sec:baseModel my:baseModel ;
+ ja:modelName "http://example.com/securedModel2" ;
+ sec:evaluatorImpl my:secEvaluator ;
+ .
+
+my:secEvaluator
+ a sec:Evaluator ;
+ sec:args [ rdf:_1 "true"^^xsd:boolean ;
+ rdf:_2 "false"^^xsd:boolean ;
+ rdf:_3 "true"^^xsd:boolean ;
+ rdf:_4 "true"^^xsd:boolean ;
+ rdf:_5 "true"^^xsd:boolean ;
+ rdf:_6 "false"^^xsd:boolean ;
+ ] ;
+ sec:evaluatorClass "org.apache.jena.security.MockSecurityEvaluator" ;
+ .
+
\ No newline at end of file