/******************************************************************************* * Copyright (c) 2011 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cambridge Semantics Incorporated *******************************************************************************/ package com.cambridgesemantics.anzo.sdk.api; import org.openanzo.client.AnzoClient; import org.openanzo.client.AnzoClientConfigurationFactory; import org.openanzo.client.ClientGraph; import org.openanzo.ontologies.openanzo.NamedGraph; import org.openanzo.rdf.Constants; import org.openanzo.rdf.INamedGraph; import org.openanzo.rdf.URI; import org.openanzo.rdf.utils.UriGenerator; /** * * This simple example demonstrates how access control statements can limit which users and read, add, or remove statements from a graph. This example works * against the ready-to-run standalone server. *

* In this example, we create various graphs as one user and grant some access to those graphs to various other users. Then we log on as those users and show * how the access control statements affect access those users have. * * @author Jordi Albornoz Mulligan ( jordi@cambridgesemantics.com */ public class GraphPermissions { public static void main(String[] args) throws Exception { String username = "default"; String password = "123"; String host = "localhost"; int port = 61616; boolean useSsl = false; // Create some URIs which will identify the various graphs we want to create for the example. URI unrestrictedAccessNamedGraphURI = Constants.valueFactory.createURI("http://example.org/unrestrictedAccessNamedGraph"); URI onlyCreatorAccessNamedGraphURI = Constants.valueFactory.createURI("http://example.org/onlyCreatorAccessNamedGraph"); URI readonlyAccessNamedGraphURI = Constants.valueFactory.createURI("http://example.org/readonlyAccessNamedGraphURI"); // First we'll connect as user 'default' and create various graphs and set their access control. AnzoClient anzoClient = null; try { // Instantiate and connect the AnzoClient to the server. anzoClient = new AnzoClient(AnzoClientConfigurationFactory.createJMSConfiguration(username, password, host, port, useSsl)); anzoClient.connect(); // Always use try-finally to make sure the graphs are closed. ClientGraph unrestrictedAccessReplicaGraph = null; ClientGraph onlyCreatorAccessReplicaGraph = null; ClientGraph readonlyAccessReplicaGraph = null; try { URI res1 = Constants.valueFactory.createURI("http://example.org/res1"); URI prop1 = Constants.valueFactory.createURI("http://example.org/prop1"); // Start a transaction in which we will create the graphs, add some statements to them, and set their access control. anzoClient.begin(); try { unrestrictedAccessReplicaGraph = anzoClient.getReplicaGraph(unrestrictedAccessNamedGraphURI); onlyCreatorAccessReplicaGraph = anzoClient.getReplicaGraph(onlyCreatorAccessNamedGraphURI); readonlyAccessReplicaGraph = anzoClient.getReplicaGraph(readonlyAccessNamedGraphURI); // Add some statements to the graphs just so that they have some content. unrestrictedAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value1")); unrestrictedAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value2")); onlyCreatorAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value3")); onlyCreatorAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value4")); readonlyAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value3")); readonlyAccessReplicaGraph.add(res1, prop1, Constants.valueFactory.createLiteral("value4")); // Access control statements must go inside the graph's metadata graph. // In Anzo, you can control what users/groups can read the statements of a graph, // what users/groups can add statements to a graph, and what users/groups can remove // statements from a graph. You control that by adding statements that use the // anzo:canBeReadBy, anzo:canBeAddedToBy, and anzo:canBeRemovedFromBy predicates, respectively. // The object of an access control statement must be the URI of the user, not the user name. // Anzo also defines some special built-in URIs to denote some special groups: // http://openanzo.org/Role/everyone - a built-in group that includes all users // http://openanzo.org/Role/authenticatedUsers - a built-in group that includes all users except the // built-in anzo_anonymous user (only relevant if anonymous access is enabled). // // In Anzo, a user can be marked as a 'sysadmin'. A sysadmin user has all access to all data and operations // in the Anzo server regardless of what the access control statements of a graph may be. There is always a // built-in user called 'sysadmin' which is marked as such (analogous to 'root' in unix). However, any user // can be configured to be a sysadmin if they are made a member of the group configured to denote sysadmins // in the configuration. You can check if the current user is a sysadmin by using the AnzoPrincipal isSysadmin // method. For example, anzoClient.getServicePrincipal().isSysadmin(). // // An ACL statement must contain the graph URI or graph's metadata graph URI as the subject of // the statement. The graph itself and the metadata graph actually have different sets of of permissions. // That allows you to give add/remove access to a graph without also having to give add/remove // access on the metadata graph. Thus, for example, you can give a user access to change the graph // contents but not grant him access to change the access control for the graph. // NOTE: If you want a user to be able to read the contents of a graph, then must have read access // to BOTH the graph and the metadata graph. // Setup the unrestrictedAccessReplicaGraph to grant all access to everyone. INamedGraph unrestrictedGraphMetadata = unrestrictedAccessReplicaGraph.getMetadataGraph(); // Set access control for the graph itself. unrestrictedGraphMetadata.add(unrestrictedAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeReadByProperty, Constants.EVERYONE_ROLE); unrestrictedGraphMetadata.add(unrestrictedAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, Constants.EVERYONE_ROLE); unrestrictedGraphMetadata.add(unrestrictedAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, Constants.EVERYONE_ROLE); // Set access control for its metadata graph. unrestrictedGraphMetadata.add(unrestrictedGraphMetadata.getNamedGraphUri(), NamedGraph.canBeReadByProperty, Constants.EVERYONE_ROLE); unrestrictedGraphMetadata.add(unrestrictedGraphMetadata.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, Constants.EVERYONE_ROLE); unrestrictedGraphMetadata.add(unrestrictedGraphMetadata.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, Constants.EVERYONE_ROLE); // Setup the onlyCreatorAccessReplicaGraph to grant only access to the creator. INamedGraph onlyCreatorGraphMetadata = onlyCreatorAccessReplicaGraph.getMetadataGraph(); URI currentUserUri = anzoClient.getServicePrincipal().getUserURI(); // Set access control for the graph itself. onlyCreatorGraphMetadata.add(onlyCreatorAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeReadByProperty, currentUserUri); onlyCreatorGraphMetadata.add(onlyCreatorAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, currentUserUri); onlyCreatorGraphMetadata.add(onlyCreatorAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, currentUserUri); // Set access control for its metadata graph. onlyCreatorGraphMetadata.add(onlyCreatorGraphMetadata.getNamedGraphUri(), NamedGraph.canBeReadByProperty, currentUserUri); onlyCreatorGraphMetadata.add(onlyCreatorGraphMetadata.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, currentUserUri); onlyCreatorGraphMetadata.add(onlyCreatorGraphMetadata.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, currentUserUri); // Setup the readonlyGraphMetadata to all access to the creator and just read access to everyone else. INamedGraph readonlyGraphMetadata = readonlyAccessReplicaGraph.getMetadataGraph(); // Set access control for the graph itself. readonlyGraphMetadata.add(readonlyAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeReadByProperty, Constants.EVERYONE_ROLE); readonlyGraphMetadata.add(readonlyAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, currentUserUri); readonlyGraphMetadata.add(readonlyAccessReplicaGraph.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, currentUserUri); // Set access control for its metadata graph. readonlyGraphMetadata.add(readonlyGraphMetadata.getNamedGraphUri(), NamedGraph.canBeReadByProperty, Constants.EVERYONE_ROLE); readonlyGraphMetadata.add(readonlyGraphMetadata.getNamedGraphUri(), NamedGraph.canBeAddedToByProperty, currentUserUri); readonlyGraphMetadata.add(readonlyGraphMetadata.getNamedGraphUri(), NamedGraph.canBeRemovedFromByProperty, currentUserUri); // NOTE: If you create a graph without setting any access control statements at all, then the server will // automatically set some default access control statements. Typically those give at least the creator // full access. If you do pass in any access control statements when creating a graph, then the server // will NOT add any of the default access control statements. A common mistake to create a new graph just adding // two statements to give everyone read access. Doing so means that even the creator won't be able to modify that // graph since the server won't add its default statements and no statements sent up give add/remove access. anzoClient.commit(); } catch (Exception e) { anzoClient.abort(); throw e; } anzoClient.updateRepository(); } finally { if (unrestrictedAccessReplicaGraph != null) { unrestrictedAccessReplicaGraph.close(); } if (onlyCreatorAccessReplicaGraph != null) { onlyCreatorAccessReplicaGraph.close(); } if (readonlyAccessReplicaGraph != null) { readonlyAccessReplicaGraph.close(); } } } finally { if (anzoClient != null) { anzoClient.close(); } } // Now log in as various users and display whether they can read/write each of the graphs. URI[] graphUris = { unrestrictedAccessNamedGraphURI, onlyCreatorAccessNamedGraphURI, readonlyAccessNamedGraphURI }; String[] usernames = { "default", "defaultNoRights", "sysadmin" }; for (String user : usernames) { // First we'll connect as user 'default' and create various graphs and set their access control. anzoClient = null; try { // Instantiate and connect the AnzoClient to the server. anzoClient = new AnzoClient(AnzoClientConfigurationFactory.createJMSConfiguration(user, password, host, port, useSsl)); anzoClient.connect(); for (URI graphUri : graphUris) { System.out.println("Access to graph <" + graphUri + "> as user '" + user + "' (isSysadmin: " + anzoClient.getServicePrincipal().isSysadmin() + "):"); boolean canRead = anzoClient.canReadNamedGraph(graphUri); boolean canAdd = anzoClient.canAddToNamedGraph(graphUri); boolean canRemove = anzoClient.canRemoveFromNamedGraph(graphUri); URI metadataGraphUri = UriGenerator.generateMetadataGraphUri(graphUri); boolean canReadMetadata = anzoClient.canReadNamedGraph(metadataGraphUri); boolean canAddMetadata = anzoClient.canAddToNamedGraph(metadataGraphUri); boolean canRemoveMetadata = anzoClient.canRemoveFromNamedGraph(metadataGraphUri); System.out.println("\tRead:" + canRead); System.out.println("\tAdd:" + canAdd); System.out.println("\tRemove:" + canRemove); System.out.println("\tRead Metadata:" + canReadMetadata); System.out.println("\tAdd Metadata:" + canAddMetadata); System.out.println("\tRemove Metadata:" + canRemoveMetadata); } } finally { if (anzoClient != null) { anzoClient.close(); } } } } }