This is an automated email from the ASF dual-hosted git repository. andy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit 7b8af45250f4fc87a372ee81c485d30b3878a7ed Author: Andy Seaborne <[email protected]> AuthorDate: Wed May 21 20:50:38 2025 +0100 GH-2805: StatementTerm for jena-permissions --- .../java/org/apache/jena/permissions/Factory.java | 4 +- .../permissions/model/SecuredStatementTerm.java | 28 ++++++ .../permissions/model/impl/SecuredLiteralImpl.java | 14 ++- .../permissions/model/impl/SecuredModelImpl.java | 4 +- .../permissions/model/impl/SecuredRDFNodeImpl.java | 24 ++--- .../model/impl/SecuredResourceImpl.java | 27 ++---- .../model/impl/SecuredStatementImpl.java | 1 - .../model/impl/SecuredStatementTermImpl.java | 105 +++++++++++++++++++++ 8 files changed, 165 insertions(+), 42 deletions(-) diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/Factory.java b/jena-permissions/src/main/java/org/apache/jena/permissions/Factory.java index 49178c6f3e..08a71441a8 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/Factory.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/Factory.java @@ -34,7 +34,7 @@ public class Factory { /** * Create an instance of the SecuredGraph - * + * * @param securityEvaluator The security evaluator to use * @param graphIRI The IRI for the graph. * @param graph The graph that we are wrapping. @@ -48,7 +48,7 @@ public class Factory { /** * Get an instance of SecuredModel - * + * * @param securityEvaluator The security evaluator to use * @param modelIRI The securedModel IRI (graph IRI) to evaluate * against. diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/SecuredStatementTerm.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/SecuredStatementTerm.java new file mode 100644 index 0000000000..74b633c64f --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/SecuredStatementTerm.java @@ -0,0 +1,28 @@ +/* + * 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.permissions.model; + +import org.apache.jena.rdf.model.*; + +/** + * The interface for secured StatementTerm instances. + * + * Use a secured Model to create instances. + */ +public interface SecuredStatementTerm extends StatementTerm, SecuredRDFNode { +} diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java index 06e5bd5a45..2c5be5e4cb 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java @@ -25,10 +25,8 @@ import org.apache.jena.permissions.impl.SecuredItemInvoker; import org.apache.jena.permissions.model.SecuredLiteral; import org.apache.jena.permissions.model.SecuredModel; import org.apache.jena.permissions.model.SecuredResource; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.RDFVisitor; -import org.apache.jena.rdf.model.ResourceRequiredException; +import org.apache.jena.permissions.model.SecuredStatementTerm; +import org.apache.jena.rdf.model.*; import org.apache.jena.shared.AuthenticationRequiredException; import org.apache.jena.shared.ReadDeniedException; @@ -100,6 +98,14 @@ public class SecuredLiteralImpl extends SecuredRDFNodeImpl implements SecuredLit throw new ResourceRequiredException(NodeFactory.createLiteralString("Can not read")); } + @Override + public SecuredStatementTerm asStatementTerm() { + if (canRead()) { + throw new StmtTermRequiredException(asNode()); + } + throw new StmtTermRequiredException(NodeFactory.createLiteralString("Can not read")); + } + /** * @sec.graph Read * @throws ReadDeniedException diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java index 5b9d762652..c491e125cd 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java @@ -1345,8 +1345,8 @@ public class SecuredModelImpl extends SecuredItemImpl implements SecuredModel { } @Override - public RDFNode createStatementTerm(Statement statement) { - return SecuredResourceImpl.getInstance(holder.getSecuredItem(), holder.getBaseItem().createStatementTerm(statement)); + public StatementTerm createStatementTerm(Statement statement) { + return SecuredStatementTermImpl.getInstance(holder.getSecuredItem(), holder.getBaseItem().createStatementTerm(statement)); } @Override diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java index 203b133c01..09ee7eafe9 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java @@ -6,9 +6,9 @@ * 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. @@ -28,10 +28,7 @@ import org.apache.jena.permissions.impl.SecuredItemImpl; import org.apache.jena.permissions.model.SecuredModel; import org.apache.jena.permissions.model.SecuredRDFNode; import org.apache.jena.permissions.model.SecuredUnsupportedPolymorphismException; -import org.apache.jena.rdf.model.Literal; -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.rdf.model.*; import org.apache.jena.shared.AuthenticationRequiredException; import org.apache.jena.shared.ReadDeniedException; @@ -40,7 +37,7 @@ import org.apache.jena.shared.ReadDeniedException; */ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements SecuredRDFNode { /** - * + * * @param securedModel the Secured Model to use. * @param rdfNode the node to secure. * @return the secured RDFNode @@ -49,6 +46,9 @@ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements Secu if (rdfNode instanceof Literal) { return SecuredLiteralImpl.getInstance(securedModel, (Literal) rdfNode); } + if (rdfNode instanceof StatementTerm ) { + return SecuredStatementTermImpl.getInstance(securedModel, (StatementTerm)rdfNode); + } return SecuredResourceImpl.getInstance(securedModel, (Resource) rdfNode); } @@ -60,7 +60,7 @@ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements Secu /** * Constructor - * + * * @param securedModel the Secured Model to use. * @param holder the item holder that will contain this SecuredRDFNode. */ @@ -198,8 +198,8 @@ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements Secu } @Override - public boolean isStmtResource() { - return holder.getBaseItem().isStmtResource(); + public boolean isStatementTerm() { + return holder.getBaseItem().isStatementTerm(); } /** @@ -208,7 +208,7 @@ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements Secu * asNode, because we allow other implementations of Resource, at least in * principle. This is deemed to be a complete and correct interpretation of * RDFNode equality, which is why this method has been marked final. - * + * * @param o An object to test for equality with this node * @return True if o is equal to this node. * @throws ReadDeniedException @@ -222,7 +222,7 @@ public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements Secu /** * The hash code of an RDFnode is defined to be the same as the underlying node. - * + * * @return The hashcode as an int */ @Override diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java index cbde1532a9..2caf65b862 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java @@ -297,6 +297,12 @@ public class SecuredResourceImpl extends SecuredRDFNodeImpl implements SecuredRe return holder.getSecuredItem(); } + @Override + public StatementTerm asStatementTerm() { + checkRead(); + throw new StmtTermRequiredException(asNode()); + } + @Override public SecuredResource begin() { holder.getBaseItem().begin(); @@ -505,27 +511,6 @@ public class SecuredResourceImpl extends SecuredRDFNodeImpl implements SecuredRe return holder.getBaseItem().getURI(); } - /** - * @sec.graph Read - * - * if {@link SecurityEvaluator#isHardReadError()} is true and the - * user does not have read access then @{code null} is returned. - * - * @throws ReadDeniedException - * @throws AuthenticationRequiredException if user is not authenticated and is - * required to be. - */ - @Override - public Statement getStmtTerm() { - if (checkSoftRead()) { - Statement stmt = holder.getBaseItem().getStmtTerm(); - if (stmt != null && canRead(stmt)) { - return SecuredStatementImpl.getInstance(getModel(), stmt); - } - } - return null; - } - /** * @sec.graph Read * @sec.triple Read SecTriple(this,p,o) diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java index 59d800280b..4862cabcae 100644 --- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java @@ -457,7 +457,6 @@ public class SecuredStatementImpl extends SecuredItemImpl implements SecuredStat checkRead(holder.getBaseItem().asTriple()); final RDFNode rdfNode = holder.getBaseItem().getObject(); return SecuredRDFNodeImpl.getInstance(getModel(), rdfNode); - } /** diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementTermImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementTermImpl.java new file mode 100644 index 0000000000..fac6f7afc4 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementTermImpl.java @@ -0,0 +1,105 @@ +/* + * 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.permissions.model.impl; + +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemInvoker; +import org.apache.jena.permissions.model.*; +import org.apache.jena.rdf.model.*; + +/** + * Implementation of SecuredStatement to be used by a SecuredItemInvoker proxy. + */ +public class SecuredStatementTermImpl extends SecuredRDFNodeImpl implements SecuredStatementTerm { + /** + * get a SecuredStatement + * + * @param securedModel The secured model that provides the security context + * @param stmt The statement to secure. + * @return the SecuredStatement + */ + public static SecuredStatementTerm getInstance(final SecuredModel securedModel, final StatementTerm stmtTerm) { + if (securedModel == null) { + throw new IllegalArgumentException("Secured securedModel may not be null"); + } + if (stmtTerm == null) { + throw new IllegalArgumentException("StatemenTerm may not be null"); + } + + final ItemHolder<StatementTerm, SecuredStatementTerm> holder = new ItemHolder<>(stmtTerm); + + final SecuredStatementTermImpl checker = new SecuredStatementTermImpl(securedModel, holder); + // if we are going to create a duplicate proxy, just return this + // one. + if (stmtTerm instanceof SecuredStatementTerm) { + if (checker.isEquivalent((SecuredStatement) stmtTerm)) { + return (SecuredStatementTerm) stmtTerm; + } + } + return holder.setSecuredItem(new SecuredItemInvoker(holder.getBaseItem().getClass(), checker)); + } + + // the item holder that contains this SecuredStatement. + private final ItemHolder<StatementTerm, SecuredStatementTerm> holder; + + private final SecuredModel securedModel; + + /** + * Constructor. + * + * @param securityEvaluator The security evaluator to use. + * @param graphIRI the graph IRI to verify against. + * @param holder The item holder that will contain this + * SecuredStatement. + */ + private SecuredStatementTermImpl(final SecuredModel securedModel, + final ItemHolder<StatementTerm, SecuredStatementTerm> holder) { + super(securedModel, holder); + this.holder = holder; + this.securedModel = securedModel; + } + + @Override + public SecuredLiteral asLiteral() { + checkRead(); + throw new LiteralRequiredException(asNode()); + } + + @Override + public SecuredResource asResource() { + checkRead(); + throw new ResourceRequiredException(asNode()); + } + + @Override + public SecuredStatementTerm asStatementTerm() { + checkRead(); + return this; + } + + @Override + public Statement getStatement() { + checkRead(); + return SecuredStatementImpl.getInstance(securedModel, holder.getBaseItem().getStatement()); + } + + @Override + public Object visitWith(RDFVisitor rv) { + return rv.visitStmt(this, this.getStatement()); + } +}
