From 8919c5001d958fb9ab3b1ebbcf8c98dc7d240d2e Mon Sep 17 00:00:00 2001 From: Christoph Braun Date: Wed, 22 Apr 2026 15:29:35 +0200 Subject: [PATCH] initial design for conditions (starting with client) --- README.md | 33 ++--- .../edu/kit/aifb/solid/wac/example/App.java | 41 +++--- .../kit/aifb/solid/wac/query/WacEngine.java | 132 ++++++++++++++++++ .../wac/query/conditions/ConditionQuery.java | 83 +++++++++++ .../conditions/ConditionQueryBuilder.java | 83 +++++++++++ .../wac/query/conditions/Conditions.java | 9 ++ .../client/ClientConditionEngine.java | 12 ++ .../conditions/client/QueryForClient.java | 57 ++++++++ .../client/QueryForClientGroup.java | 117 ++++++++++++++++ .../client/QueryForPublicClient.java | 50 +++++++ .../{WacQuery.java => core/AgentQuery.java} | 13 +- .../AgentQueryBuilder.java} | 32 ++--- .../wac/query/core/AgentQueryEngine.java | 23 +++ .../wac/query/{ => core}/QueryForAgent.java | 18 ++- .../query/{ => core}/QueryForAgentGroup.java | 26 ++-- .../{ => core}/QueryForAuthenticated.java | 18 ++- .../wac/query/{ => core}/QueryForPublic.java | 24 ++-- .../kit/aifb/solid/wac/example/AppTest.java | 86 ++++++------ 18 files changed, 716 insertions(+), 141 deletions(-) create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/WacEngine.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQuery.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQueryBuilder.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/Conditions.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/ClientConditionEngine.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClient.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClientGroup.java create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForPublicClient.java rename src/main/java/edu/kit/aifb/solid/wac/query/{WacQuery.java => core/AgentQuery.java} (89%) rename src/main/java/edu/kit/aifb/solid/wac/query/{WacQueryBuilder.java => core/AgentQueryBuilder.java} (84%) create mode 100644 src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryEngine.java rename src/main/java/edu/kit/aifb/solid/wac/query/{ => core}/QueryForAgent.java (80%) rename src/main/java/edu/kit/aifb/solid/wac/query/{ => core}/QueryForAgentGroup.java (84%) rename src/main/java/edu/kit/aifb/solid/wac/query/{ => core}/QueryForAuthenticated.java (75%) rename src/main/java/edu/kit/aifb/solid/wac/query/{ => core}/QueryForPublic.java (68%) diff --git a/README.md b/README.md index 6a61b27..931e705 100644 --- a/README.md +++ b/README.md @@ -31,26 +31,19 @@ We then assume that the triples describing access control rules are placed in th * @param webid if != null, it is assumed to be authenticated * @param envResourceMap appplication environment resource map * @param envResourceAclMap application environement resource to + * @param clientid the client id of th client/app the agent uses (might be null) * corresponding aclRDF map * @return the URI String of the matching access control rule or * {@code null} if none matches * */ - public static String checkAccessControl(String resource, String method, String body, String webid, Map envResourceMap, WacMapping envResourceAclMap) { - // get the query builder for the resource (may look for inherited rules) - WacQueryBuilder queryBuilder = WacQueryBuilder - .newBuilder(envResourceMap, envResourceAclMap) - .forRequest(resource, method, body) - .byAgent(webid); - WacQuery[] queries = queryBuilder.build(); - for (WacQuery query : queries) { - String ruleMatch = query.exec(); - if (ruleMatch == null) { - continue; - } - return ruleMatch; - } - return null; + public static String checkAccessControl(String resource, String method, String body, String webid, Map envResourceMap, WacMapping envResourceAclMap, String clientid) { + WacEngine engine = WacEngine + .newEngine(envResourceMap, envResourceAclMap) + .forRequest(resource, method, body) + .byAgent(webid) + .withClient(clientid); + return engine.check(); } ``` By the way, WAC does not really define behaviour for the HTTP method OPTIONS. @@ -58,7 +51,7 @@ OPTIONS is common for CORS pre-flight requests. Be sure to hanlde OPTIONS manually. Otherwise you may keep wondering why your code does not work. -Want to run an example directly? Naybe something like: +Want to run an example directly? Maybe something like: ```java /** * example usage @@ -73,11 +66,12 @@ Want to run an example directly? Naybe something like: String acl = envResourceAclMap.getAcl(resource); System.out.println("ACL: " + acl); String someAcl = """ - @prefix acl: + @prefix acl: . <#testAgentGroupAccess> a acl:Authorization; acl:agent ; acl:accessTo ; - acl:mode acl:Write. + acl:mode acl:Write; + acl:condition [ a acl:ClientCondition; acl:client ]. """; // Create an RDF dataset by parsing the Turtle data Dataset dataset = DatasetFactory.create(); @@ -90,6 +84,7 @@ Want to run an example directly? Naybe something like: envResourceMap.put(acl, dataset); // mock a HTTP request String webid = "http://example.org/webid"; + String clientid = "http://example.org/clientid"; String method = "PATCH"; String body = """ @prefix solid: . @@ -101,7 +96,7 @@ Want to run an example directly? Naybe something like: solid:deletes { ?person ex:givenName \"Claudia\". }. """; // check WAC rules - String ruleGrantingAccess = checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String ruleGrantingAccess = checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, clientid); // result System.out.println("\nAccess granted? " + ((ruleGrantingAccess == null) ? "No." : "Yes: " + ruleGrantingAccess)); // happy hacking diff --git a/src/main/java/edu/kit/aifb/solid/wac/example/App.java b/src/main/java/edu/kit/aifb/solid/wac/example/App.java index 9107d4a..9d648b0 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/example/App.java +++ b/src/main/java/edu/kit/aifb/solid/wac/example/App.java @@ -13,8 +13,7 @@ import org.apache.jena.riot.RDFDataMgr; import edu.kit.aifb.solid.wac.WacMapping; -import edu.kit.aifb.solid.wac.query.WacQuery; -import edu.kit.aifb.solid.wac.query.WacQueryBuilder; +import edu.kit.aifb.solid.wac.query.WacEngine; /** * Example usage @@ -39,21 +38,13 @@ public class App { * {@code null} if none matches * */ - public static String checkAccessControl(String resource, String method, String body, String webid, Map envResourceMap, WacMapping envResourceAclMap) { - // get the query builder for the resource (may look for inherited rules) - WacQueryBuilder queryBuilder = WacQueryBuilder - .newBuilder(envResourceMap, envResourceAclMap) - .forRequest(resource, method, body) - .byAgent(webid); - WacQuery[] queries = queryBuilder.build(); - for (WacQuery query : queries) { - String ruleMatch = query.exec(); - if (ruleMatch == null) { - continue; - } - return ruleMatch; - } - return null; + public static String checkAccessControl(String resource, String method, String body, String webid, Map envResourceMap, WacMapping envResourceAclMap, String clientid) { + WacEngine engine = WacEngine + .newEngine(envResourceMap, envResourceAclMap) + .forRequest(resource, method, body) + .byAgent(webid) + .withClient(clientid); + return engine.check(); } /** @@ -64,16 +55,17 @@ public static String checkAccessControl(String resource, String method, String b public static void main(String[] args) { // mock application environment WacMapping envResourceAclMap = new ResourceAclMap(); // ! IMPLEMENTATION DEPENDENT - Map envResourceMap = new HashMap<>(); // ! IMPLEMENTATION DEPENDENT + Map envResourceDatasetMap = new HashMap<>(); // ! IMPLEMENTATION DEPENDENT String resource = "http://localhost:8080/marmotta/ldp/test"; String acl = envResourceAclMap.getAcl(resource); System.out.println("ACL: " + acl); String someAcl = """ - @prefix acl: - <#testAgentGroupAccess> a acl:Authorization; + @prefix acl: . + <#testAuthz> a acl:Authorization; acl:agent ; acl:accessTo ; - acl:mode acl:Write. + acl:mode acl:Write; + acl:condition [ a acl:ClientCondition; acl:client ]. """; // Create an RDF dataset by parsing the Turtle data Dataset dataset = DatasetFactory.create(); @@ -81,11 +73,12 @@ public static void main(String[] args) { InputStream stream = new ByteArrayInputStream(someAcl.getBytes(StandardCharsets.UTF_8)); RDFDataMgr.read(aclRDF, stream, acl, Lang.TTL); // Access the dataset - System.out.println("RDF Dataset:"); + System.out.println("ACL of the Dataset:"); dataset.getDefaultModel().write(System.out, "TTL"); // Example: Turtle format - envResourceMap.put(acl, dataset); + envResourceDatasetMap.put(acl, dataset); // mock a HTTP request String webid = "http://example.org/webid"; + String clientid = "http://example.org/clientid"; String method = "PATCH"; String body = """ @prefix solid: . @@ -97,7 +90,7 @@ public static void main(String[] args) { solid:deletes { ?person ex:givenName \"Claudia\". }. """; // check WAC rules - String ruleGrantingAccess = checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String ruleGrantingAccess = checkAccessControl(resource, method, body, webid, envResourceDatasetMap, envResourceAclMap, clientid); // result System.out.println("\nAccess granted? " + ((ruleGrantingAccess == null) ? "No." : "Yes: " + ruleGrantingAccess)); // happy hacking diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/WacEngine.java b/src/main/java/edu/kit/aifb/solid/wac/query/WacEngine.java new file mode 100644 index 0000000..43c4a14 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/WacEngine.java @@ -0,0 +1,132 @@ +package edu.kit.aifb.solid.wac.query; + +import java.util.List; +import java.util.Map; +import org.apache.jena.query.Dataset; +import edu.kit.aifb.solid.wac.WacMapping; +import edu.kit.aifb.solid.wac.query.conditions.ConditionQuery; +import edu.kit.aifb.solid.wac.query.conditions.ConditionQueryBuilder; +import edu.kit.aifb.solid.wac.query.conditions.client.ClientConditionEngine; +import edu.kit.aifb.solid.wac.query.core.AgentQuery; +import edu.kit.aifb.solid.wac.query.core.AgentQueryBuilder; +import edu.kit.aifb.solid.wac.query.core.AgentQueryEngine; + +/** + * A builder-pattern for ACL Queries. + */ +public class WacEngine implements AgentQueryEngine, ClientConditionEngine { + + /** + * + * Get a query builder in the current application environment: + * + * @param envResourceMap a mapping of URI string to RDF datasets, s.t. the + * query may look up data, .acl or specific + * agentGroups. + * @param envResourceAclMap a mapping of URI string of a resource to its + * corresponding .acl + * @return a new builder (for the provided environment) + */ + public static WacEngine newEngine(Map envResourceMap, WacMapping envResourceAclMap) { + return new WacEngine(envResourceMap, envResourceAclMap); + } + + private WacEngine(Map resourceMap, WacMapping resourceAclMap) { + this.resourceMap = resourceMap; + this.resourceAclMap = resourceAclMap; + } + + // RESOURCE DATA (-> for lookup of resources, e.g. .acl and resources of + // agentGroup) + private final Map resourceMap; + + // RESOURCE-ACL MAP (-> isForControlRequest) + private final WacMapping resourceAclMap; + + // REQUEST DATA + private String resource; + private String method; + private String body; + private String webId; + private String clientId; + + /** + * Set the action used to access the resource. + * + * @param resource + * @param method + * @param body + * @return the builder + */ + public WacEngine forRequest(String resource, String method, String body) { + this.resource = resource; + this.method = method; + this.body = body; + return this; + } + + /** + * Set the webid of the accessing agent. Remains {@code null} if unknown. + * + * @param webId + * @return the builder + */ + public WacEngine byAgent(String webId) { + this.webId = webId; + return this; + } + + /** + * Set the clientId of the accessing client. Remains {@code null} if unknown. + * + * @param clientId + * @return the builder + */ + public WacEngine withClient(String clientId) { + this.clientId = clientId; + return this; + } + + public WacEngine clear() { + this.resource = null; + this.method = null; + this.body = null; + this.webId = null; + this.clientId = null; + return this; + } + + public String check() { + // agent + AgentQueryBuilder queryBuilder = AgentQueryBuilder + .newBuilder(this.resourceMap, this.resourceAclMap) + .forRequest(this.resource, this.method, this.body) + .byAgent(this.webId); + AgentQuery[] queries = queryBuilder.build(); + // conditions + ConditionQueryBuilder conditionBuilder = ConditionQueryBuilder + .newBuilder(this.resourceMap) + .withClient(this.clientId); + // exec + for (AgentQuery query : queries) { + List ruleMatches = query.exec(); + if (ruleMatches.size() == 0) { + continue; + } + + for (String authorization : ruleMatches) { + ConditionQuery[] conditions = conditionBuilder + .onAuthorization(authorization) + .build(); + for (ConditionQuery condition : conditions) { + if (!condition.isTrue()) { + continue; + } + return authorization; + } + } + } + return null; + } + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQuery.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQuery.java new file mode 100644 index 0000000..3d5ad72 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQuery.java @@ -0,0 +1,83 @@ +package edu.kit.aifb.solid.wac.query.conditions; + +import org.apache.jena.query.Dataset; + +import edu.kit.aifb.solid.wac.Namespaces; + +/** + * Just a little abstract class to provide the base functionality for + * ConditionQueries. Concrete implementations of this class specify how it is + * expressed which conditions must hold on an authorization, e.g. using + * {@code appendToQueryBGPs(String bgps)}. + * + * See also {@link AuthenticationContextVariable} + * + */ +public abstract class ConditionQuery { + + private String authorizationURI; + protected final Dataset authoritativeACL; + private String queryBGPs; + private String conditionType; + + public ConditionQuery(Dataset inAuthoritativeACL, String onAuthorization, String forConditionType) { + this.authoritativeACL = inAuthoritativeACL; + this.authorizationURI = onAuthorization; + this.conditionType = forConditionType; + + StringBuilder queryBGPsb = new StringBuilder(); + + // basic + String typeTriple = " <" + this.authorizationURI + "> a acl:Authorization ."; + queryBGPsb.append(typeTriple); + queryBGPsb.append("\n"); + + // condition not exists + String notExistsPattern = "{ FILTER NOT EXISTS { <" + this.authorizationURI + "> acl:condition [ a <" + this.conditionType + "> ] . }}"; + queryBGPsb.append(notExistsPattern); + queryBGPsb.append("\n"); + + // save to String + queryBGPs = queryBGPsb.toString(); + + // ! what particular condition? + // implementations of this class should + // (1) UNION the triples for the condition type (e.g., public client / client webid / client group), e.g. using appendToQueryBGPs(...) + // (2) specify how these BGPs are used in a query or multiple queries in exec(). + } + + protected void unionToQueryBGPs(String bgps) { + this.queryBGPs += "UNION { " + bgps + " }\n"; + } + + @Deprecated + protected void appendToQueryBGPs(String bgps) { + this.queryBGPs += bgps; + } + + protected String getQueryBGPs() { + return this.queryBGPs; + } + + /** + * You may want to override this method, e.g. if you want to do link + * traversal e.g. for clientGroup. + * + * @return a basic query string + */ + protected String getQueryWithCurrentBGPs() { + return String.format(""" + PREFIX acl: <%s> + ASK WHERE { + %s + } + """, Namespaces.ACL, this.queryBGPs); + } + + /** + * execute the query + * + * @return whether or not the conditions (if any) listed on the authorization are satisfied + */ + public abstract boolean isTrue(); +} \ No newline at end of file diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQueryBuilder.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQueryBuilder.java new file mode 100644 index 0000000..e31bd16 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/ConditionQueryBuilder.java @@ -0,0 +1,83 @@ +package edu.kit.aifb.solid.wac.query.conditions; + +import java.util.Map; +import org.apache.jena.query.Dataset; + +import edu.kit.aifb.solid.wac.query.conditions.client.QueryForClient; +import edu.kit.aifb.solid.wac.query.conditions.client.QueryForClientGroup; +import edu.kit.aifb.solid.wac.query.conditions.client.QueryForPublicClient; + +/** + * A builder-pattern for ACL Condition Queries ({@link Conditions}). + */ +public class ConditionQueryBuilder { + + /** + * + * Get a query builder in the current application environment: + * + * @param authoritativeACL the dataset containing the authoritative ACL statements to check conditions with + * @param envResourceMap a mapping of URI string to RDF datasets, s.t. the + * query may look up data, .acl or specific agentGroups + * @return a new builder (for the provided environment) + */ + public static ConditionQueryBuilder newBuilder(Map envResourceMap) { + return new ConditionQueryBuilder(envResourceMap); + } + + private ConditionQueryBuilder(Map resourceMap) { + this.resourceMap = resourceMap; + } + + // RESOURCE DATA (-> for lookup of resources, e.g. .acl and resources of agentGroup) + private final Map resourceMap; + + private String authorizationURI; + private String clientId; + + + /** + * Set the authorization used to access the resource. + * + * @param resource + * @param method + * @param body + * @return the builder + */ + public ConditionQueryBuilder onAuthorization(String authorizationURI) { + this.authorizationURI = authorizationURI; + return this; + } + + /** + * Set the clientId of the accessing client. Remains {@code null} if unknown. + * + * @param clientId + * @return the builder + */ + public ConditionQueryBuilder withClient(String clientId) { + this.clientId = clientId; + return this; + } + + /** + * Build all {@link ConditionQuery} from the information currently in the builder. + * + * @return the {@link ConditionQuery} array of length 1 (if webid is {@code null}, + * no valid authentication assumed) or length 4 (if webid provided, valid + * authentication assumed) + */ + public ConditionQuery[] build() { + Dataset authoritativeACL = this.resourceMap.get(this.authorizationURI.split("#")[0]); // get authoritative Dataset for Rule + ConditionQuery pub = new QueryForPublicClient(authoritativeACL, this.authorizationURI); + if (this.clientId == null) { + ConditionQuery[] result = {pub}; + return result; + } + ConditionQuery client = new QueryForClient(authoritativeACL, this.authorizationURI, this.clientId); + ConditionQuery group = new QueryForClientGroup(authoritativeACL, this.authorizationURI, this.clientId, this.resourceMap); + ConditionQuery[] result = {pub, client, group}; + return result; + } + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/Conditions.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/Conditions.java new file mode 100644 index 0000000..a41ca27 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/Conditions.java @@ -0,0 +1,9 @@ +package edu.kit.aifb.solid.wac.query.conditions; + +import edu.kit.aifb.solid.wac.Namespaces; + +public class Conditions { + + public static final String ClientCondition = Namespaces.ACL + "ClientCondition"; + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/ClientConditionEngine.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/ClientConditionEngine.java new file mode 100644 index 0000000..a08934a --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/ClientConditionEngine.java @@ -0,0 +1,12 @@ +package edu.kit.aifb.solid.wac.query.conditions.client; + +public interface ClientConditionEngine { + + /** + * Set the clientId of the accessing client. Remains {@code null} if unknown. + * + * @param clientId + * @return the builder + */ + public ClientConditionEngine withClient(String clientId); +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClient.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClient.java new file mode 100644 index 0000000..7eb079c --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClient.java @@ -0,0 +1,57 @@ +package edu.kit.aifb.solid.wac.query.conditions.client; + +import org.apache.jena.query.Dataset; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; + +import edu.kit.aifb.solid.wac.query.conditions.ConditionQuery; +import edu.kit.aifb.solid.wac.query.conditions.Conditions; + +/** + *
+ * ASK 
+ * WHERE {  
+ *     $authorization 
+ *     {
+ *       # (a) No known condition is present. 
+ *       FILTER NOT EXISTS { 
+ *         $authorization acl:condition ?condition .
+ *         ?condition a acl:ClientCondition .
+ *       }
+ *     }
+ *     UNION 
+ *     {
+ *       # (b) A condition is present and it matches the specified client.
+ *       $authorization acl:condition [ a acl:ClientCondition; acl:client $client ] .
+ *     }
+ *   }
+ * }
+ * 
+ */ +public class QueryForClient extends ConditionQuery { + + private String authorizationURI; + private String withClient; + + public QueryForClient(Dataset inAuthoritativeACL, String onAuthorization, String withClient) { + super(inAuthoritativeACL, onAuthorization, Conditions.ClientCondition); + this.authorizationURI = onAuthorization; + if (withClient == null) { + throw new IllegalArgumentException("Cannot build client query for client `null`"); + } + this.withClient = withClient; + String clientTriple = "<" + this.authorizationURI + "> acl:condition [ a <"+ Conditions.ClientCondition +">; acl:client <" + withClient + "> ] ."; + this.unionToQueryBGPs(clientTriple); + } + + @Override + public boolean isTrue() { + if (this.withClient == null) { + throw new IllegalArgumentException("Cannot execute agent query for webid `null`"); + } + String queryString = this.getQueryWithCurrentBGPs(); + QueryExecution qexec = QueryExecutionFactory.create(queryString, this.authoritativeACL); + return qexec.execAsk(); + } + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClientGroup.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClientGroup.java new file mode 100644 index 0000000..ec02e52 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForClientGroup.java @@ -0,0 +1,117 @@ +package edu.kit.aifb.solid.wac.query.conditions.client; + +import java.util.Map; + +import org.apache.jena.query.Dataset; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; + +import edu.kit.aifb.solid.wac.Namespaces; +import edu.kit.aifb.solid.wac.query.conditions.ConditionQuery; +import edu.kit.aifb.solid.wac.query.conditions.Conditions; +/** + *
+ * ASK 
+ * WHERE {  
+ *     $authorization 
+ *     {
+ *       # (a) No known condition is present. 
+ *       FILTER NOT EXISTS { 
+ *         $authorization acl:condition ?condition .
+ *         ?condition a ?conditionType .
+ *         FILTER ( ?condType IN ( acl:ClientCondition ) ) 
+ *       }
+ *     }
+ *     UNION 
+ *     {
+ *       # (b) A condition is present and it matches the specified client in a group.
+ *       $authorization acl:condition [ a acl:ClientCondition; acl:clientGroup ?group .
+ *       BIND( REPLACE(?group, "(#|#.*)", "" ) AS ?grp )
+ *     }
+ *     GRAPH ?grp {
+ *       ?group vcard:hasMember $client.
+ *     }
+ * }
+ * 
+ */ +public class QueryForClientGroup extends ConditionQuery { + + private final String VARIABLE_FOR_GROUP = "?group"; + + private String authorizationURI; + private String withClient; + private Map clientGroupsMap; + + public QueryForClientGroup(Dataset inAuthoritativeACL, String onAuthorization, String withClient, Map clientGroupsMap) { + super(inAuthoritativeACL, onAuthorization, Conditions.ClientCondition); + this.authorizationURI = onAuthorization; + if (withClient == null) { + throw new IllegalArgumentException("Cannot build client query for client `null`"); + } + this.withClient = withClient; + this.clientGroupsMap = clientGroupsMap; + String clientTriple = "<" + this.authorizationURI + "> acl:condition [ a <"+ Conditions.ClientCondition +">; acl:clientGroup" + this.VARIABLE_FOR_GROUP + " ] ."; + this.unionToQueryBGPs(clientTriple); + } + + /** + * override to also return group + */ + @Override + protected String getQueryWithCurrentBGPs() { + return String.format(""" + PREFIX acl: <%s> + SELECT %s WHERE { + %s + } + """, Namespaces.ACL, this.VARIABLE_FOR_GROUP, this.getQueryBGPs()); + } + + /** + * Dynamically generate a new query to look up the client group. + * + * @return true or false + */ + private String generateClientQueryString(String groupName) { + return String.format(""" + PREFIX vcard: + ASK WHERE { + <%s> vcard:hasMember <%s> + } + """, groupName, this.withClient); + } + + /** + * Find any applicable client group and derefence their URIs to check if the + * client is a member of any. + * + * @return whether or not the client group condition (if any) is satisfied + */ + @Override + public boolean isTrue() { + if (this.withClient == null) { + throw new IllegalArgumentException("Cannot execute agent query for webid `null`"); + } + String queryForGroupString = this.getQueryWithCurrentBGPs(); + QueryExecution qexec = QueryExecutionFactory.create(queryForGroupString, this.authoritativeACL); + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution soln = results.next(); + String groupName = soln.getResource(this.VARIABLE_FOR_GROUP).getURI(); + if (!this.clientGroupsMap.containsKey(groupName.split("#")[0])) { + continue; + } + Dataset datasetGroup = this.clientGroupsMap.get(groupName.split("#")[0]); + String queryStringForAgent = generateClientQueryString(groupName); + QueryExecution qexecAgent = QueryExecutionFactory.create(queryStringForAgent, datasetGroup); + boolean resultAgent = qexecAgent.execAsk(); + if (resultAgent) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForPublicClient.java b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForPublicClient.java new file mode 100644 index 0000000..40041e2 --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/conditions/client/QueryForPublicClient.java @@ -0,0 +1,50 @@ +package edu.kit.aifb.solid.wac.query.conditions.client; + +import org.apache.jena.query.Dataset; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; + +import edu.kit.aifb.solid.wac.query.conditions.ConditionQuery; +import edu.kit.aifb.solid.wac.query.conditions.Conditions; + +/** + *
+ * ASK 
+ * WHERE {  
+ *     $authorization 
+ *     {
+ *       # (a) No known condition is present. 
+ *       FILTER NOT EXISTS { 
+ *         $authorization acl:condition ?condition .
+ *         ?condition a ?conditionType .
+ *         FILTER ( ?condType IN ( acl:ClientCondition ) ) 
+ *       }
+ *     }
+ *     UNION 
+ *     {
+ *       # (b) A condition is present and it matches the specified clientClass to be public.
+ *       $authorization acl:condition [ a acl:ClientCondition; acl:clientClass foaf:Agent ] .
+ *     }
+ *   }
+ * }
+ * 
+ */ +public class QueryForPublicClient extends ConditionQuery { + + private String authorizationURI; + + public QueryForPublicClient(Dataset inAuthoritativeACL, String onAuthorization) { + super(inAuthoritativeACL, onAuthorization, Conditions.ClientCondition); + this.authorizationURI = onAuthorization; + String clientTriple = "<" + this.authorizationURI + "> acl:condition [ a <"+ Conditions.ClientCondition +">; acl:clientClass ] ."; + this.unionToQueryBGPs(clientTriple); + } + + @Override + public boolean isTrue() { + String queryString = this.getQueryWithCurrentBGPs(); + QueryExecution qexec = QueryExecutionFactory.create(queryString, this.authoritativeACL); + return qexec.execAsk(); + } + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/WacQuery.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQuery.java similarity index 89% rename from src/main/java/edu/kit/aifb/solid/wac/query/WacQuery.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQuery.java index 046347b..f0e330b 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/WacQuery.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQuery.java @@ -1,4 +1,6 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; + +import java.util.List; import org.apache.jena.query.Dataset; @@ -13,7 +15,7 @@ * See also {@link WacQueryType} * */ -public abstract class WacQuery { +public abstract class AgentQuery { protected final String VARIABLE_FOR_AUTHORIZATION = "?authz"; protected final Dataset authoritativeACL; @@ -26,7 +28,7 @@ public abstract class WacQuery { * @param isLookingForInheritedRule * @param forMode */ - public WacQuery(Dataset inAuthoritativeACL, String onResource, boolean isLookingForInheritedRule, String forMode) { + public AgentQuery(Dataset inAuthoritativeACL, String onResource, boolean isLookingForInheritedRule, String forMode) { this.authoritativeACL = inAuthoritativeACL; StringBuilder queryBGPsb = new StringBuilder(); @@ -85,8 +87,7 @@ protected String getQueryWithCurrentBGPs() { /** * execute the query * - * @return the {@code String} of the retrieved access control rule URI or - * {@code null} if no rule was found + * @return the {@code List} of the matching access control rule URIs */ - public abstract String exec(); + public abstract List exec(); } diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/WacQueryBuilder.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryBuilder.java similarity index 84% rename from src/main/java/edu/kit/aifb/solid/wac/query/WacQueryBuilder.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryBuilder.java index 2d513ef..ae6a879 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/WacQueryBuilder.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryBuilder.java @@ -1,4 +1,4 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -22,7 +22,7 @@ /** * A builder-pattern for ACL Queries ({@link WacQueryType}). */ -public class WacQueryBuilder { +public class AgentQueryBuilder { /** * @@ -34,11 +34,11 @@ public class WacQueryBuilder { * corresponding .acl * @return a new builder (for the provided environment) */ - public static WacQueryBuilder newBuilder(Map envResourceMap, WacMapping envResourceAclMap) { - return new WacQueryBuilder(envResourceMap, envResourceAclMap); + public static AgentQueryBuilder newBuilder(Map envResourceMap, WacMapping envResourceAclMap) { + return new AgentQueryBuilder(envResourceMap, envResourceAclMap); } - private WacQueryBuilder(Map resourceMap, WacMapping resourceAclMap) { + private AgentQueryBuilder(Map resourceMap, WacMapping resourceAclMap) { this.resourceMap = resourceMap; this.resourceAclMap = resourceAclMap; } @@ -73,7 +73,7 @@ private WacQueryBuilder(Map resourceMap, WacMapping resourceAcl * @param body * @return the builder */ - public WacQueryBuilder forRequest(String resource, String method, String body) { + public AgentQueryBuilder forRequest(String resource, String method, String body) { this.resource = resource; this.method = method; this.body = body; @@ -89,7 +89,7 @@ public WacQueryBuilder forRequest(String resource, String method, String body) { * @param webid * @return the builder */ - public WacQueryBuilder byAgent(String webid) { + public AgentQueryBuilder byAgent(String webid) { this.webid = webid; return this; } @@ -218,23 +218,23 @@ private void findAuthoritativeACL(String res) { } /** - * Build all {@link WacQuery} from the information currently in the builder. + * Build all {@link AgentQuery} from the information currently in the builder. * - * @return the {@link WacQuery} array of length 1 (if webid is {@code null}, + * @return the {@link AgentQuery} array of length 1 (if webid is {@code null}, * no valid authentication assumed) or length 4 (if webid provided, valid * authentication assumed) */ - public WacQuery[] build() { + public AgentQuery[] build() { this.findAuthoritativeACL(this.resource); // set authoritativeACL, onResource, and hasInheritedRule - WacQuery pub = new QueryForPublic(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode); + AgentQuery pub = new QueryForPublic(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode); if (this.webid == null) { - WacQuery[] result = {pub}; + AgentQuery[] result = {pub}; return result; } - WacQuery authn = new QueryForAuthenticated(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode); - WacQuery agent = new QueryForAgent(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode, this.webid); - WacQuery group = new QueryForAgentGroup(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode, this.webid, this.resourceMap); - WacQuery[] result = {pub, authn, agent, group}; + AgentQuery authn = new QueryForAuthenticated(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode); + AgentQuery agent = new QueryForAgent(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode, this.webid); + AgentQuery group = new QueryForAgentGroup(this.authoritativeACL, this.onResource, this.hasInheritedRule, this.accessMode, this.webid, this.resourceMap); + AgentQuery[] result = {pub, authn, agent, group}; return result; } diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryEngine.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryEngine.java new file mode 100644 index 0000000..8d175da --- /dev/null +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/AgentQueryEngine.java @@ -0,0 +1,23 @@ +package edu.kit.aifb.solid.wac.query.core; + +public interface AgentQueryEngine { + + /** + * Set the action used to access the resource. + * + * @param resource + * @param method + * @param body + * @return the builder + */ + public AgentQueryEngine forRequest(String resource, String method, String body); + + /** + * Set the webid of the accessing agent. Remains {@code null} if unknown. + * + * @param webid + * @return the builder + */ + public AgentQueryEngine byAgent(String webid); + +} diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgent.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgent.java similarity index 80% rename from src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgent.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgent.java index df9d7a5..f227405 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgent.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgent.java @@ -1,4 +1,7 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; + +import java.util.ArrayList; +import java.util.List; import org.apache.jena.query.Dataset; import org.apache.jena.query.QueryExecution; @@ -24,7 +27,7 @@ * } * */ -class QueryForAgent extends WacQuery { +class QueryForAgent extends AgentQuery { private String forAgentWebId; @@ -47,17 +50,18 @@ public QueryForAgent(Dataset inAuthoritativeACL, String onResource, boolean isLo } @Override - public String exec() { + public List exec() { if (this.forAgentWebId == null) { throw new IllegalArgumentException("Cannot execute agent query for webid `null`"); } String queryString = this.getQueryWithCurrentBGPs(); QueryExecution qexec = QueryExecutionFactory.create(queryString, this.authoritativeACL); - ResultSet results = qexec.execSelect(); - if (results.hasNext()) { - return results.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI(); + ResultSet bindings = qexec.execSelect(); + ArrayList result = new ArrayList<>(); // matching ACL URIs + while (bindings.hasNext()) { + result.add(bindings.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI()); } - return null; + return result; } } diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgentGroup.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgentGroup.java similarity index 84% rename from src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgentGroup.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgentGroup.java index bd01e09..4c58686 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAgentGroup.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAgentGroup.java @@ -1,5 +1,7 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.apache.jena.query.Dataset; @@ -35,7 +37,7 @@ * } * */ -class QueryForAgentGroup extends WacQuery { +class QueryForAgentGroup extends AgentQuery { private String forAgentWebId; private Map agentGroupsMap; @@ -96,25 +98,29 @@ private String generateAgentQueryString(String groupName) { * {@code null} if no rule was found */ @Override - public String exec() { + public List exec() { if (this.forAgentWebId == null) { throw new IllegalArgumentException("Cannot execute agent query for webid `null`"); } String queryForGroupString = this.getQueryWithCurrentBGPs(); QueryExecution qexec = QueryExecutionFactory.create(queryForGroupString, this.authoritativeACL); - ResultSet results = qexec.execSelect(); - while (results.hasNext()) { - QuerySolution soln = results.next(); + ResultSet bindings = qexec.execSelect(); // bindings + ArrayList result = new ArrayList<>(); // matching ACL URIs + while (bindings.hasNext()) { + QuerySolution soln = bindings.next(); String groupName = soln.getResource(this.VARIABLE_FOR_GROUP).getURI(); + if (!this.agentGroupsMap.containsKey(groupName.split("#")[0])) { + continue; + } Dataset datasetGroup = this.agentGroupsMap.get(groupName.split("#")[0]); String queryStringForAgent = generateAgentQueryString(groupName); QueryExecution qexecAgent = QueryExecutionFactory.create(queryStringForAgent, datasetGroup); - boolean resultAgent = qexecAgent.execAsk(); - if (resultAgent) { - return soln.getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI(); + boolean isMember = qexecAgent.execAsk(); + if (isMember) { + result.add(soln.getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI()); } } - return null; + return result; } } diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAuthenticated.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAuthenticated.java similarity index 75% rename from src/main/java/edu/kit/aifb/solid/wac/query/QueryForAuthenticated.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAuthenticated.java index bafdc30..28cd3c1 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForAuthenticated.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForAuthenticated.java @@ -1,4 +1,7 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; + +import java.util.ArrayList; +import java.util.List; import org.apache.jena.query.Dataset; import org.apache.jena.query.QueryExecution; @@ -24,7 +27,7 @@ * } * */ -class QueryForAuthenticated extends WacQuery { +class QueryForAuthenticated extends AgentQuery { /** * @@ -40,14 +43,15 @@ public QueryForAuthenticated(Dataset inAuthoritativeACL, String onResource, bool } @Override - public String exec() { + public List exec() { String queryString = this.getQueryWithCurrentBGPs(); QueryExecution qexec = QueryExecutionFactory.create(queryString, this.authoritativeACL); - ResultSet results = qexec.execSelect(); - if (results.hasNext()) { - return results.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI(); + ResultSet bindings = qexec.execSelect(); + ArrayList result = new ArrayList<>(); // matching ACL URIs + while (bindings.hasNext()) { + result.add(bindings.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI()); } - return null; + return result; } } diff --git a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForPublic.java b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForPublic.java similarity index 68% rename from src/main/java/edu/kit/aifb/solid/wac/query/QueryForPublic.java rename to src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForPublic.java index d4f8ded..3eabc38 100644 --- a/src/main/java/edu/kit/aifb/solid/wac/query/QueryForPublic.java +++ b/src/main/java/edu/kit/aifb/solid/wac/query/core/QueryForPublic.java @@ -1,4 +1,7 @@ -package edu.kit.aifb.solid.wac.query; +package edu.kit.aifb.solid.wac.query.core; + +import java.util.ArrayList; +import java.util.List; import org.apache.jena.query.Dataset; import org.apache.jena.query.QueryExecution; @@ -24,7 +27,7 @@ * } * */ -class QueryForPublic extends WacQuery { +class QueryForPublic extends AgentQuery { /** * @@ -33,21 +36,24 @@ class QueryForPublic extends WacQuery { * @param isLookingForInheritedRule * @param forMode */ - public QueryForPublic(Dataset inAuthoritativeACL, String onResource, boolean isLookingForInheritedRule, String forMode) { + public QueryForPublic(Dataset inAuthoritativeACL, String onResource, boolean isLookingForInheritedRule, + String forMode) { super(inAuthoritativeACL, onResource, isLookingForInheritedRule, forMode); - String agentTriple = " " + this.VARIABLE_FOR_AUTHORIZATION + " acl:agentClass ."; + String agentTriple = " " + this.VARIABLE_FOR_AUTHORIZATION + + " acl:agentClass ."; this.appendToQueryBGPs(agentTriple); } @Override - public String exec() { + public List exec() { String queryString = this.getQueryWithCurrentBGPs(); QueryExecution qexec = QueryExecutionFactory.create(queryString, this.authoritativeACL); - ResultSet results = qexec.execSelect(); - if (results.hasNext()) { - return results.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI(); + ResultSet bindings = qexec.execSelect(); + ArrayList result = new ArrayList<>(); // matching ACL URIs + while (bindings.hasNext()) { + result.add(bindings.next().getResource(this.VARIABLE_FOR_AUTHORIZATION).getURI()); } - return null; + return result; } } diff --git a/src/test/java/edu/kit/aifb/solid/wac/example/AppTest.java b/src/test/java/edu/kit/aifb/solid/wac/example/AppTest.java index a6cf275..8359369 100644 --- a/src/test/java/edu/kit/aifb/solid/wac/example/AppTest.java +++ b/src/test/java/edu/kit/aifb/solid/wac/example/AppTest.java @@ -89,7 +89,7 @@ public String getResource(String acl) { addAsNamedGraph(dataset, group, groupTTL); envResourceMap.put(group, dataset); - groupAppendAcl = address + "testAgentGroupAccessControl.acl"; + groupAppendAcl = address + "testAgentGroupAccessAppend.acl"; String groupAppendAclTTL = String.format( """ @prefix acl: . @@ -105,7 +105,7 @@ public String getResource(String acl) { addAsNamedGraph(dataset, groupAppendAcl, groupAppendAclTTL); envResourceMap.put(groupAppendAcl, dataset); - agentControlAcl = address + "testAgentAccessAppend.acl"; + agentControlAcl = address + "testAgentAccessControl.acl"; String agentControlAclTTL = String.format( """ @prefix acl: . @@ -183,7 +183,7 @@ public void testPublicAccessReadGET() { String resource = publicReadAcl.split(".acl")[0]; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(publicReadAcl + "#auth"); assertTrue("Expected: rule=<" + publicReadAcl + "#auth>; Result: rule=" + rule, ok); } @@ -193,7 +193,7 @@ public void testPublicAccessReadPATCH() { String resource = publicReadAcl.split(".acl")[0]; String method = PATCH; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -203,7 +203,7 @@ public void testPublicAccessReadPOST() { String resource = publicReadAcl.split(".acl")[0]; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -213,7 +213,7 @@ public void testPublicAccessReadPUT() { String resource = publicReadAcl.split(".acl")[0]; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -223,7 +223,7 @@ public void testPublicAccessReadDELETE() { String resource = publicReadAcl.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -236,7 +236,7 @@ public void testAuthenticatedAccessWriteUNAUTHENTICATED() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = DELETE; // random choice String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -246,7 +246,7 @@ public void testAuthenticatedAccessWriteGET() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -256,7 +256,7 @@ public void testAuthenticatedAccessWritePATCHwithDelete() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = PATCH; String body = patchInsertDelete; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(authenticatedWriteAcl + "#auth"); assertTrue("Expected: rule=<" + authenticatedWriteAcl + "#auth>; Result: rule=" + rule, ok); } @@ -266,7 +266,7 @@ public void testAuthenticatedAccessWritePATCHappendOnly() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = PATCH; String body = patchInsert; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(authenticatedWriteAcl + "#auth"); assertTrue("Expected: rule=<" + authenticatedWriteAcl + "#auth>; Result: rule=" + rule, ok); } @@ -276,7 +276,7 @@ public void testAuthenticatedAccessWritePOST() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(authenticatedWriteAcl + "#auth"); assertTrue("Expected: rule=<" + authenticatedWriteAcl + "#auth>; Result: rule=" + rule, ok); } @@ -286,7 +286,7 @@ public void testAuthenticatedAccessWritePUT() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(authenticatedWriteAcl + "#auth"); assertTrue("Expected: rule=<" + authenticatedWriteAcl + "#auth>; Result: rule=" + rule, ok); } @@ -296,7 +296,7 @@ public void testAuthenticatedAccessWriteDELETE() { String resource = authenticatedWriteAcl.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(authenticatedWriteAcl + "#auth"); assertTrue("Expected: rule=<" + authenticatedWriteAcl + "#auth>; Result: rule=" + rule, ok); } @@ -309,7 +309,7 @@ public void testGroupAccessAppendUNAUTHENTICATED() { String resource = groupAppendAcl.split(".acl")[0]; String method = PATCH; // random choice String body = patchInsertDelete; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -319,7 +319,7 @@ public void testGroupAccessAppendGET() { String resource = groupAppendAcl.split(".acl")[0]; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -329,7 +329,7 @@ public void testGroupAccessAppendPATCHwithDelete() { String resource = groupAppendAcl.split(".acl")[0]; String method = PATCH; String body = patchInsertDelete; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -339,7 +339,7 @@ public void testGroupAccessAppendPATCHappendOnly() { String resource = groupAppendAcl.split(".acl")[0]; String method = PATCH; String body = patchInsert; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(groupAppendAcl + "#auth"); assertTrue("Expected: rule=<" + groupAppendAcl + "#auth>; Result: rule=" + rule, ok); } @@ -349,7 +349,7 @@ public void testGroupAccessAppendPOST() { String resource = groupAppendAcl.split(".acl")[0]; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(groupAppendAcl + "#auth"); assertTrue("Expected: rule=<" + groupAppendAcl + "#auth>; Result: rule=" + rule, ok); } @@ -359,7 +359,7 @@ public void testGroupAccessAppendPUT() { String resource = groupAppendAcl.split(".acl")[0]; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -369,7 +369,7 @@ public void testGroupAccessAppendDELETE() { String resource = groupAppendAcl.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -382,7 +382,7 @@ public void testAgentAccessControlUNAUTHENTICATED() { String resource = agentControlAcl; String method = PUT; // random choice String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -392,7 +392,7 @@ public void testAgentAccessControlGET() { String resource = agentControlAcl; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -402,7 +402,7 @@ public void testAgentAccessControlPATCHwithDelete() { String resource = agentControlAcl; String method = PATCH; String body = patchInsertDelete; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -412,7 +412,7 @@ public void testAgentAccessControlPATCHappendOnly() { String resource = agentControlAcl; String method = PATCH; String body = patchInsert; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -422,7 +422,7 @@ public void testAgentAccessControlPOST() { String resource = agentControlAcl; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -432,7 +432,7 @@ public void testAgentAccessControlPUT() { String resource = agentControlAcl; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -442,7 +442,7 @@ public void testAgentAccessControlDELETE() { String resource = agentControlAcl; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(agentControlAcl + "#auth"); assertTrue("Expected: rule=<" + agentControlAcl + "#auth>; Result: rule=" + rule, ok); } @@ -453,7 +453,7 @@ public void testAgentAccessControlUNAUTHENTICATEDrescoure() { String resource = agentControlAcl.split(".acl")[0]; String method = GET; // random choice String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -463,7 +463,7 @@ public void testAgentAccessControlGETresource() { String resource = agentControlAcl.split(".acl")[0]; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -473,7 +473,7 @@ public void testAgentAccessControlPATCHwithDeleteResource() { String resource = agentControlAcl.split(".acl")[0]; String method = PATCH; String body = patchInsertDelete; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -483,7 +483,7 @@ public void testAgentAccessControlPATCHappendOnlyResource() { String resource = agentControlAcl.split(".acl")[0]; String method = PATCH; String body = patchInsert; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -493,7 +493,7 @@ public void testAgentAccessControlPOSTresource() { String resource = agentControlAcl.split(".acl")[0]; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -503,7 +503,7 @@ public void testAgentAccessControlPUTresource() { String resource = agentControlAcl.split(".acl")[0]; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -513,7 +513,7 @@ public void testAgentAccessControlDELETEresource() { String resource = agentControlAcl.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -526,7 +526,7 @@ public void testAccessControlUNAUTHENTICATEDNotFound() { String resource = noAclFound.split(".acl")[0]; String method = PUT; // random choice String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -536,7 +536,7 @@ public void testAccessControlNotFoundGET() { String resource = noAclFound.split(".acl")[0]; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -546,7 +546,7 @@ public void testAccessControlNotFoundDelete() { String resource = noAclFound.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -556,7 +556,7 @@ public void testAccessControlNotFoundndAppendOnly() { String resource = noAclFound.split(".acl")[0]; String method = PATCH; String body = patchInsert; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -566,7 +566,7 @@ public void testAccessControlNotFoundolPOST() { String resource = noAclFound.split(".acl")[0]; String method = POST; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -576,7 +576,7 @@ public void testAccessControlNotFoundPUT() { String resource = noAclFound.split(".acl")[0]; String method = PUT; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -586,7 +586,7 @@ public void testAccessControlNotFoundDELETE() { String resource = noAclFound.split(".acl")[0]; String method = DELETE; String body = ""; - String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, webid, envResourceMap, envResourceAclMap, null); boolean ok = (rule == null); assertTrue("Expected: rule=null; Result: rule=" + rule, ok); } @@ -599,7 +599,7 @@ public void testAccessControlUNAUTHENTICATEDInheritedPublicRead() { String resource = containerWithAcl.split(".acl")[0] + "someContainer/someFile"; String method = GET; String body = ""; - String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap); + String rule = App.checkAccessControl(resource, method, body, null, envResourceMap, envResourceAclMap, null); boolean ok = (rule != null) && rule.equals(containerWithAcl + "#auth"); assertTrue("Expected: rule=<" + containerWithAcl + "#auth>; Result: rule=" + rule, ok); }