/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package fedora.test.api; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import junit.framework.Test; import junit.framework.TestSuite; import fedora.client.FedoraClient; import fedora.server.access.FedoraAPIA; import fedora.server.management.FedoraAPIM; import fedora.server.security.servletfilters.xmluserfile.FedoraUsers; import fedora.server.types.gen.Property; import fedora.server.utilities.ServerUtility; import fedora.server.utilities.StreamUtility; import fedora.test.DemoObjectTestSetup; import fedora.test.FedoraServerTestCase; /** * Tests involving XACML policies, for API-A and API-M. * * Note: Although these tests can run when API-A AuthN is off, for the best * coverage, make sure the server is configured to authenticate for API-A * access. * * @author Edwin Shin */ public class TestXACMLPolicies extends FedoraServerTestCase { private FedoraClient admin; private FedoraClient testuser1; private FedoraClient testuserroleA; private FedoraClient testuser2; private FedoraClient testuser3; private FedoraClient testuserroleB; private FedoraClient testuserroleC; private FedoraClient testuserroleC2; private FedoraClient testuser4; private File fedoraUsersBackup = null; public static Test suite() { TestSuite suite = new TestSuite("XACML Policy TestSuite"); suite.addTestSuite(TestXACMLPolicies.class); return new DemoObjectTestSetup(suite); } public void testXACMLMultiOwnerAccess() throws Exception { // demo:MultiOwnerObject is owned by fedoraAdmin and testuser1 final String pid = "test:MultiOwnerObject"; final String owners = "fedoraAdmin,testuser1"; addTestObject(pid, owners, null); // should only be modifiable by an owner try { assertTrue(canWrite(admin, pid)); assertTrue(canWrite(testuser1, pid)); assertFalse(canWrite(testuserroleA, pid)); } finally { removeTestObject(pid); } } public void testXACMLUnmodifiableContentModel() throws Exception { // test policy disallows modifyObject for test:RestrictedCModel final String unrestrictedCModel = "test:UnrestrictedCModel"; final String restrictedCModel = "test:RestrictedCModel"; final String hasUnrestricted = "test:HasUnrestrictedCModel"; addTestObject(hasUnrestricted, null, unrestrictedCModel); final String hasRestricted = "test:HasRestrictedCModel"; addTestObject(hasRestricted, null, restrictedCModel); final String hasUnrestrictedAndRestricted = "test:HasUnrestrictedAndRestrictedCModel"; addTestObject(hasUnrestrictedAndRestricted, null, unrestrictedCModel, restrictedCModel); final String hasRestrictedAndUnrestricted = "test:HasRestrictedAndUnrestrictedCModel"; addTestObject(hasRestrictedAndUnrestricted, null, restrictedCModel, unrestrictedCModel); try { assertTrue(canWrite(admin, hasUnrestricted)); assertFalse(canWrite(admin, hasRestricted)); assertFalse(canWrite(admin, hasUnrestrictedAndRestricted)); assertFalse(canWrite(admin, hasRestrictedAndUnrestricted)); } finally { removeTestObject(hasUnrestricted); removeTestObject(hasRestricted); removeTestObject(hasUnrestrictedAndRestricted); removeTestObject(hasRestrictedAndUnrestricted); } } private boolean canWrite(FedoraClient client, String pid) throws Exception { FedoraAPIM apim = client.getAPIM(); try { apim.modifyObject(pid, null, null, null, "log message"); return true; } catch (Exception e) { return false; } } public void testXACMLAPIMAccess() throws Exception { String dateOfFirstSuccess = null; String dateOfSecondSuccess = null; String dateOfThirdSuccess = null; String dateOfFourthSuccess = null; String URL1 = getDemoBaseURL() + "/simple-image-demo/col1.jpg"; String URL2 = getDemoBaseURL() + "/simple-image-demo/col2.jpg"; String URL3 = getDemoBaseURL() + "/simple-image-demo/col3.jpg"; Class modDSArgs[] = {String.class, String.class, String[].class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, Boolean.TYPE}; Object modDSParms1[] = {"demo:5", "THUMBRES_IMG", null, null, null, null, null, null, null, null, Boolean.FALSE}; Class purgeDSArgs[] = {String.class, String.class, String.class, String.class, String.class, Boolean.TYPE}; Object purgeDSParms1[] = {"demo:5", "THUMBRES_IMG", null, null, null, Boolean.FALSE}; Class setVersionableArgs[] = {String.class, String.class, Boolean.TYPE, String.class}; Object setVersionableFalse[] = {"demo:5", "THUMBRES_IMG", Boolean.FALSE, null}; Object setVersionableTrue[] = {"demo:5", "THUMBRES_IMG", Boolean.TRUE, null}; // APIM access by user without access- should fail // testuserroleA does not have permission to modify a datastream, so this should fail invokeAPIMFailure(testuserroleA, "testuserroleA", "modifyDatastreamByReference", modDSArgs, modDSParms1); //APIM accesses by users with access- should succeed modDSParms1[6] = URL1; dateOfFirstSuccess = invokeAPIMSuccessString(testuser1, "testuser1", "modifyDatastreamByReference", modDSArgs, modDSParms1); System.out.println(" URL = " + modDSParms1[6]); assertTrue(dateOfFirstSuccess != null); System.out.println(" Modify datastream from testuser1 succeeded."); System.out.println("Disabling versioning."); invokeAPIMSuccess(admin, "admin", "setDatastreamVersionable", setVersionableArgs, setVersionableFalse); modDSParms1[6] = URL2; System.out .println("Testing modify datastream from admin with versioning off."); dateOfSecondSuccess = invokeAPIMSuccessString(admin, "admin", "modifyDatastreamByReference", modDSArgs, modDSParms1); System.out.println(" URL = " + modDSParms1[6]); assertTrue(dateOfSecondSuccess != null); System.out.println(" Modify datastream from admin succeeded."); modDSParms1[6] = null; modDSParms1[3] = "The Colliseum with Graffiti"; System.out .println("Testing modify datastream from admin with versioning off just changing label."); dateOfThirdSuccess = invokeAPIMSuccessString(admin, "admin", "modifyDatastreamByReference", modDSArgs, modDSParms1); System.out.println(" Label = " + modDSParms1[3]); assertTrue(dateOfThirdSuccess != null); System.out.println(" Modify datastream from admin succeeded."); System.out.println("Re-enabling versioning."); invokeAPIMSuccess(admin, "admin", "setDatastreamVersionable", setVersionableArgs, setVersionableTrue); modDSParms1[6] = URL3; modDSParms1[3] = null; dateOfFourthSuccess = invokeAPIMSuccessString(testuser1, "testuser1", "modifyDatastreamByReference", modDSArgs, modDSParms1); System.out.println(" URL = " + modDSParms1[6]); assertTrue(dateOfFourthSuccess != null); System.out.println(" Modify datastream from testuser1 succeeded."); // APIM access by user without access- should fail purgeDSParms1[2] = dateOfFirstSuccess; purgeDSParms1[3] = dateOfFourthSuccess; // testuser1 does not have permission to purge a datastream, so this should fail invokeAPIMFailure(testuser1, "testuser1", "purgeDatastream", purgeDSArgs, purgeDSParms1); //APIM access by user without access- should fail // testuserroleA does have permission to to purge a datastream, but only if // datastream is in Deleted(D) state. Datastream here is still in Active(A) state // so this should fail invokeAPIMFailure(testuserroleA, "testuserroleA", "purgeDatastream", purgeDSArgs, purgeDSParms1); //APIM access by user with access- should succeed // fedoraAdmin does have permission to purge a datastream regardless of the // datastream state. Datastream here is in Acive(A) state so purge should still suceed. String purged[] = invokeAPIMSuccessStringArray(admin, "admin", "purgeDatastream", purgeDSArgs, purgeDSParms1); System.out.println(" Checking number of versions purged."); assertEquals(purged.length, 2); System.out.println(" Checking dates of versions purged."); assertEquals(purged[0], dateOfThirdSuccess); assertEquals(purged[1], dateOfFourthSuccess); System.out.println("Purge Datastreams successful."); } public void testXACMLAPIAAccess() throws Exception { if (isAPIAAuthzOn()) { Class getDDArgs[] = {String.class, String.class, String.class}; Object getDDParms[] = {"demo:5", "THUMBRES_IMG", null}; Object getDDParms2[] = {"demo:29", "url", null}; Object getDDParms3[] = {"demo:31", "DS1", null}; Object getDDParms4[] = {"demo:ObjSpecificTest", "DC", null}; Class getDissArgs[] = {String.class, String.class, String.class, Property[].class, String.class}; Object getDissParms[] = {"demo:5", "demo:1", "getHigh", null, null}; Object getDissParms2[] = {"demo:29", "demo:27", "grayscaleImage", null, null}; Class modObjArgs[] = {String.class, String.class, String.class, String.class, String.class}; Object modObjParms[] = {"demo:31", null, null, null, null}; // APIA access by user without access- should fail // testuser2 does not have permission to access api-a at all, so this should fail invokeAPIAFailure(testuser2, "testuser2", "getDatastreamDissemination", getDDArgs, getDDParms); // APIA access by user without access- should fail // testuser3 does not have permission to access Datastreams named THUMBRES_IMG, so this should fail invokeAPIAFailure(testuser3, "testuser3", "getDatastreamDissemination", getDDArgs, getDDParms); // APIA access by user without access- should fail // testuserroleB does not have permission to access HighRes Dissemenations, so this should fail invokeAPIAFailure(testuserroleB, "testuserroleB", "getDissemination", getDissArgs, getDissParms); // APIA access by user without access- should fail // testuser4 does not have permission to access demo:29 at all, so this should fail invokeAPIAFailure(testuser4, "testuser4", "getDatastreamDissemination", getDDArgs, getDDParms2); // APIA access by user without access- should fail // testuser4 does not have permission to access demo:29 at all, so this should fail invokeAPIAFailure(testuser4, "testuser4", "getDissemination", getDissArgs, getDissParms2); // APIA access by user without access- should fail // testuser1 does not have permission to access demo:29 datastreams, so this should fail invokeAPIAFailure(testuser1, "testuser1", "getDatastreamDissemination", getDDArgs, getDDParms2); // APIA access by user with access- should succeed // testuserroleC does have permission to access demo:29 datastreams, so this should succeed invokeAPIASuccess(testuserroleC, "testuserroleC", "getDatastreamDissemination", getDDArgs, getDDParms2); // Make sure object-specific policies in the POLICY datastream work addObjectSpecificPolicies(); try { // APIA access by user with access- should succeed // testuserroleC does have permission to access demo:ObjSpecificTest datastreams, so this should succeed invokeAPIASuccess(testuserroleC, "testuserroleC", "getDatastreamDissemination", getDDArgs, getDDParms4); // APIA access by user without access- should fail // demo:ObjSpecificTest's object-specific policy explicitly denies access // to user with role roleUntrusted invokeAPIAFailure(testuserroleC2, "testuserroleC2", "getDatastreamDissemination", getDDArgs, getDDParms4); } finally { removeObjectSpecificPolicies(); } // APIA access by user with access- should succeed // testuser1 does have permission to access demo:5 datastreams, so this should succeed invokeAPIASuccess(testuser1, "testuser1", "getDatastreamDissemination", getDDArgs, getDDParms); // APIA access by user who is not owner should fail // testuser1 is not currently owner of demo:31, so this should fail invokeAPIAFailure(testuser1, "testuser1", "getDatastreamDissemination", getDDArgs, getDDParms3); modObjParms[3] = "testuser1"; String dateOfSuccess = invokeAPIMSuccessString(admin, "fedoraAdmin", "modifyObject", modObjArgs, modObjParms); assertTrue(dateOfSuccess != null); System.out.println(" Modify Object from admin succeeded."); // APIA access by user who is now the owner, should succeed // testuser1 is now currently owner of demo:31, so this should succeed invokeAPIASuccess(testuser1, "testuser1", "getDatastreamDissemination", getDDArgs, getDDParms3); modObjParms[3] = "fedoraAdmin"; dateOfSuccess = invokeAPIMSuccessString(admin, "fedoraAdmin", "modifyObject", modObjArgs, modObjParms); assertTrue(dateOfSuccess != null); System.out.println(" Modify Object from admin succeeded."); } else { System.out.println("Authorization is not enabled for APIA"); System.out .println("Testing Policies for APIA access will not work."); } } public void invokeAPIMFailure(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { // APIA access by user without access- should fail try { System.out.println("Testing " + functionToTest + " from invalid user: " + username); FedoraAPIM apim1 = user.getAPIM(); Method func = apim1.getClass().getMethod(functionToTest, args); Object result = func.invoke(apim1, parms); fail("Illegal access allowed"); } catch (InvocationTargetException ite) { Throwable cause = ite.getCause(); if (cause instanceof org.apache.axis.AxisFault) { org.apache.axis.AxisFault af = (org.apache.axis.AxisFault) cause; System.out.println(" Reason = " + af.getFaultReason().substring(af.getFaultReason() .lastIndexOf(".") + 1)); assertTrue(af.getFaultReason().contains("AuthzDeniedException")); System.out.println("Access denied correctly"); } else { System.out.println("Got exception: " + cause.getClass().getName()); fail("Illegal access dis-allowed for some other reason"); } } catch (IOException ioe) { System.out .println(" Reason = " + ioe.getMessage()/* .substring(ioe.getMessage().lastIndexOf("[")) */); assertTrue(ioe.getMessage().contains("[403 Forbidden]")); System.out.println("Access denied correctly"); // exception was expected, all is A-OK } catch (Exception ae) { System.out.println("Some other exception: " + ae.getClass().getName()); fail("Some other exception"); } } public String invokeAPIMSuccessString(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { Object result = invokeAPIMSuccess(user, username, functionToTest, args, parms); return (String) result; } public String[] invokeAPIMSuccessStringArray(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { Object result = invokeAPIMSuccess(user, username, functionToTest, args, parms); return (String[]) result; } public Object invokeAPIMSuccess(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { // APIA access by user with access- should succeed try { // testuser1 does have permission to access demo:5 datastreams, so this should succeed System.out.println("Testing " + functionToTest + " from valid user: " + username); FedoraAPIM apim1 = user.getAPIM(); Method func = apim1.getClass().getMethod(functionToTest, args); Object result = func.invoke(apim1, parms); assertTrue(result != null); return result; } catch (InvocationTargetException ite) { Throwable cause = ite.getCause(); if (cause instanceof org.apache.axis.AxisFault) { org.apache.axis.AxisFault af = (org.apache.axis.AxisFault) cause; System.out.println("Got exception: " + af.getClass().getName()); System.out.println("Reason = " + af.getFaultReason()); System.out.println("Message = " + af.getMessage()); fail("Legal access dis-allowed"); } else { System.out.println("Got exception: " + cause.getClass().getName()); fail("Legal access dis-allowed"); } } catch (Exception e) { System.out.println("Got exception: " + e.getClass().getName()); fail("Legal access dis-allowed"); } return null; } public void invokeAPIAFailure(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { // APIA access by user without access- should fail try { System.out.println("Testing " + functionToTest + " from invalid user: " + username); FedoraAPIA apia1 = user.getAPIA(); Method func = apia1.getClass().getMethod(functionToTest, args); Object result = func.invoke(apia1, parms); fail("Illegal access allowed"); } catch (InvocationTargetException ite) { Throwable cause = ite.getCause(); if (cause instanceof org.apache.axis.AxisFault) { org.apache.axis.AxisFault af = (org.apache.axis.AxisFault) cause; System.out.println(" Reason = " + af.getFaultReason().substring(af.getFaultReason() .lastIndexOf(".") + 1)); assertTrue(af.getFaultReason().contains("AuthzDeniedException")); System.out.println("Access denied correctly"); } else { System.out.println("Got exception: " + cause.getClass().getName()); fail("Illegal access dis-allowed for some other reason"); } } catch (IOException ioe) { System.out.println(" Reason = " + ioe.getMessage().substring(ioe.getMessage() .lastIndexOf("["))); assertTrue(ioe.getMessage().contains("[403 Forbidden]")); System.out.println("Access denied correctly"); // exception was expected, all is A-OK } catch (Exception ae) { System.out.println("Some other exception: " + ae.getClass().getName()); fail("Illegal access dis-allowed for some other reason"); } } public Object invokeAPIASuccess(FedoraClient user, String username, String functionToTest, Class args[], Object parms[]) { // APIA access by user with access- should succeed try { // testuser1 does have permission to access demo:5 datastreams, so this should succeed System.out.println("Testing " + functionToTest + " from valid user: " + username); FedoraAPIA apia1 = user.getAPIA(); Method func = apia1.getClass().getMethod(functionToTest, args); Object result = func.invoke(apia1, parms); assertTrue(result != null); System.out.println("Access succeeded"); return result; } catch (InvocationTargetException ite) { Throwable cause = ite.getCause(); if (cause instanceof org.apache.axis.AxisFault) { org.apache.axis.AxisFault af = (org.apache.axis.AxisFault) cause; System.out.println("Got exception: " + af.getClass().getName()); System.out.println("Reason = " + af.getFaultReason()); System.out.println("Message = " + af.getMessage()); fail("Legal access dis-allowed"); } else { System.out.println("Got exception: " + cause.getClass().getName()); fail("Legal access dis-allowed"); } } catch (Exception e) { System.out.println("Got exception: " + e.getClass().getName()); fail("Legal access dis-allowed"); } return null; } public boolean isAPIAAuthzOn() throws IOException { File installProperties = new File(FEDORA_HOME, "install/install.properties"); BufferedReader prop = null; try { prop = new BufferedReader(new FileReader(installProperties)); String line = null; while ((line = prop.readLine()) != null) { if (line.startsWith("apia.auth.required")) { if (line.equals("apia.auth.required=true")) { return true; } if (line.equals("apia.auth.required=false")) { return false; } } } return false; } finally { if (prop != null) { prop.close(); } } } public void installJunitPolicies() { System.out.println("Copying Policies For Testing"); File junitDir = new File("src/test/resources/XACMLTestPolicies/junit"); File junitsaveDir = new File(FEDORA_HOME, "data/fedora-xacml-policies/repository-policies/junit"); if (!junitsaveDir.exists()) { junitsaveDir.mkdir(); } File list[] = getFilesInDir(junitDir); traverseAndCopy(list, junitsaveDir); System.out.println("Copying Policies succeeded"); } private void deleteJunitPolicies() { System.out.println("Removing Policies For Testing"); File junitsaveDir = new File(FEDORA_HOME, "data/fedora-xacml-policies/repository-policies/junit"); if (junitsaveDir.exists()) { File list[] = getFilesInDir(junitsaveDir); traverseAndDelete(list); junitsaveDir.delete(); } } private File[] getFilesInDir(File dir) { File srcFiles[] = dir.listFiles(new java.io.FilenameFilter() { public boolean accept(File dir, String name) { if ((name.toLowerCase().startsWith("permit") || name .toLowerCase().startsWith("deny")) && name.endsWith(".xml")) { return true; } return false; } }); return srcFiles; } private void traverseAndCopy(File srcFiles[], File destDir) { for (File element : srcFiles) { File destFile = new File(destDir, element.getName()); System.out.println("Copying policy: " + element.getName()); if (!destFile.exists()) { try { destFile.createNewFile(); } catch (IOException e) { throw new RuntimeException(e); } } copyFile(element, destFile); } } private void traverseAndDelete(File newFiles[]) { for (File element : newFiles) { System.out.println("Deleting policy: " + element.getName()); element.delete(); } } private boolean copyFile(File src, File dest) { InputStream in; try { in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); StreamUtility.pipeStream(in, out, 1024); return true; } catch (IOException e) { throw new RuntimeException(e); } } private void reloadPolicies() { System.out.println("Reloading Policies..."); try { FedoraClient client = new FedoraClient(ServerUtility.getBaseURL(getProtocol()), getUsername(), getPassword()); client.reloadPolicies(); System.out.println(" Done Reloading Policies"); } catch (Exception e) { throw new RuntimeException(e); } } private void backupFedoraUsersFile() { fedoraUsersBackup = new File(FedoraUsers.fedoraUsersXML.getAbsolutePath() + ".backup"); System.out.println("Backing Up Fedora Users"); if (!fedoraUsersBackup.exists()) { try { fedoraUsersBackup.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } copyFile(FedoraUsers.fedoraUsersXML, fedoraUsersBackup); } private void restoreFedoraUsersFile() { System.out.println("Restoring Fedora Users"); if (!fedoraUsersBackup.exists()) { return; } copyFile(fedoraUsersBackup, FedoraUsers.fedoraUsersXML); } private void createNewFedoraUsersFileWithTestUsers() { String sep = System.getProperty("line.seperator"); if (sep == null) { sep = "\n"; } String data = "<?xml version='1.0' ?> " + sep + "<fedora-users>" + sep + " <user name=\"" + getUsername() + "\" password=\"" + getPassword() + "\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>administrator</value>" + sep + " </attribute>" + sep + " </user>" + sep + " <user name=\"fedoraIntCallUser\" password=\"changeme\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>fedoraInternalCall-1</value>" + sep + " <value>fedoraInternalCall-2</value>" + sep + " </attribute>" + sep + " </user>" + sep + " <user name=\"testuser1\" password=\"testuser1\"/>" + sep + " <user name=\"testuser2\" password=\"testuser2\"/>" + sep + " <user name=\"testuser3\" password=\"testuser3\"/>" + sep + " <user name=\"testuser4\" password=\"testuser4\"/>" + sep + " <user name=\"testuserroleA\" password=\"testuserroleA\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>roleA</value>" + sep + " </attribute>" + sep + " </user>" + sep + " <user name=\"testuserroleB\" password=\"testuserroleB\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>roleB</value>" + sep + " </attribute>" + sep + " </user>" + sep + " <user name=\"testuserroleC\" password=\"testuserroleC\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>roleC</value>" + sep + " </attribute>" + sep + " </user>" + sep + " <user name=\"testuserroleC2\" password=\"testuserroleC2\">" + sep + " <attribute name=\"fedoraRole\">" + sep + " <value>roleC</value>" + sep + " <value>roleUntrusted</value>" + sep + " </attribute>" + sep + " </user>" + sep + " </fedora-users>"; try { FileOutputStream fu = new FileOutputStream(FedoraUsers.fedoraUsersXML); OutputStreamWriter pw = new OutputStreamWriter(fu); pw.write(data); pw.close(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void setUp() throws Exception { System.out.println("setting Up XACML test"); admin = getFedoraClient(); backupFedoraUsersFile(); createNewFedoraUsersFileWithTestUsers(); installJunitPolicies(); reloadPolicies(); System.out.println("creating alternate users"); testuser1 = new FedoraClient(getBaseURL(), "testuser1", "testuser1"); testuserroleA = new FedoraClient(getBaseURL(), "testuserroleA", "testuserroleA"); testuser2 = new FedoraClient(getBaseURL(), "testuser2", "testuser2"); testuser3 = new FedoraClient(getBaseURL(), "testuser3", "testuser3"); testuserroleB = new FedoraClient(getBaseURL(), "testuserroleB", "testuserroleB"); testuserroleC = new FedoraClient(getBaseURL(), "testuserroleC", "testuserroleC"); testuserroleC2 = new FedoraClient(getBaseURL(), "testuserroleC2", "testuserroleC2"); testuser4 = new FedoraClient(getBaseURL(), "testuser4", "testuser4"); System.out.println("done setting up"); } private void addObjectSpecificPolicies() { try { StringBuffer xml = new StringBuffer(); xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); xml.append("<foxml:digitalObject VERSION=\"1.1\" PID=\"demo:ObjSpecificTest\" xmlns:foxml=\"info:fedora/fedora-system:def/foxml#\">"); xml.append(" <foxml:objectProperties>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#state\" VALUE=\"A\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#label\" VALUE=\"ObjSpecificTest\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#createdDate\" VALUE=\"2004-12-10T00:21:57Z\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/view#lastModifiedDate\" VALUE=\"2004-12-10T00:21:57Z\"/>"); xml.append(" </foxml:objectProperties>"); xml.append(" <foxml:datastream ID=\"POLICY\" CONTROL_GROUP=\"X\" STATE=\"A\">"); xml.append(" <foxml:datastreamVersion FORMAT_URI=\"" + XACML_POLICY1_0.uri + "\" ID=\"POLICY1.0\" MIMETYPE=\"text/xml\" LABEL=\"Policy\">"); xml.append(" <foxml:xmlContent>"); xml.append("<Policy PolicyId=\"POLICY\" RuleCombiningAlgId=\"urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable\""); xml.append(" xmlns=\"urn:oasis:names:tc:xacml:1.0:policy\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"); xml.append(" <Description>"); xml.append(" Denies all to user with id testuserroleC2"); xml.append(" </Description>"); xml.append(" <Target>"); xml.append(" <Subjects>"); xml.append(" <AnySubject/>"); xml.append(" </Subjects>"); xml.append(" <Resources>"); xml.append(" <AnyResource/>"); xml.append(" </Resources>"); xml.append(" <Actions>"); xml.append(" <AnyAction/>"); xml.append(" </Actions>"); xml.append(" </Target>"); xml.append(" <Rule Effect=\"Deny\" RuleId=\"1\">"); xml.append(" <Condition FunctionId=\"urn:oasis:names:tc:xacml:1.0:function:string-is-in\">"); xml.append(" <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">roleUntrusted</AttributeValue>"); xml.append(" <SubjectAttributeDesignator AttributeId=\"fedoraRole\""); xml.append(" DataType=\"http://www.w3.org/2001/XMLSchema#string\" MustBePresent=\"false\"/>"); xml.append(" </Condition>"); xml.append(" </Rule>"); xml.append("</Policy>"); xml.append(" </foxml:xmlContent>"); xml.append(" </foxml:datastreamVersion>"); xml.append(" </foxml:datastream>"); xml.append("</foxml:digitalObject>"); admin.getAPIM().ingest(xml.toString().getBytes("UTF-8"), FOXML1_1.uri, ""); } catch (Exception e) { throw new RuntimeException("Failure adding object-specific " + "policies", e); } } private void removeObjectSpecificPolicies() { try { admin.getAPIM().purgeObject("demo:ObjSpecificTest", "", false); } catch (Exception e) { throw new RuntimeException("Failure removing object-specific " + "policies", e); } } private void addTestObject(String pid, String ownerId, String... cModelPIDs) { try { StringBuffer xml = new StringBuffer(); xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); xml.append("<foxml:digitalObject VERSION=\"1.1\" PID=\"" + pid + "\" xmlns:foxml=\"info:fedora/fedora-system:def/foxml#\">"); xml.append(" <foxml:objectProperties>"); if (ownerId != null && ownerId.trim().length() > 0) { xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#ownerId\" VALUE=\""); xml.append(ownerId.trim()); xml.append("\"/>"); } xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#state\" VALUE=\"A\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#label\" VALUE=\"MultiOwnerObject\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/model#createdDate\" VALUE=\"2004-12-10T00:21:57Z\"/>"); xml.append(" <foxml:property NAME=\"info:fedora/fedora-system:def/view#lastModifiedDate\" VALUE=\"2004-12-10T00:21:57Z\"/>"); xml.append(" </foxml:objectProperties>"); if (cModelPIDs != null) { xml.append("<foxml:datastream CONTROL_GROUP=\"X\" ID=\"RELS-EXT\">"); xml.append(" <foxml:datastreamVersion CREATED=\"2008-07-02T05:09:43.375Z\" FORMAT_URI=\"info:fedora/fedora-system:FedoraRELSExt-1.0\" ID=\"RELS-EXT1.0\" LABEL=\"RDF Statements about this object\" MIMETYPE=\"application/rdf+xml\">"); xml.append(" <foxml:xmlContent>"); xml.append(" <rdf:RDF xmlns:fedora-model=\"info:fedora/fedora-system:def/model#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">"); xml.append(" <rdf:Description rdf:about=\"info:fedora/" + pid + "\">"); for (String cModelPID: cModelPIDs) { xml.append(" <fedora-model:hasModel rdf:resource=\"info:fedora/" + cModelPID + "\"/>"); } xml.append(" </rdf:Description>"); xml.append(" </rdf:RDF>"); xml.append(" </foxml:xmlContent>"); xml.append(" </foxml:datastreamVersion>"); xml.append("</foxml:datastream>"); } xml.append("</foxml:digitalObject>"); admin.getAPIM().ingest(xml.toString().getBytes("UTF-8"), FOXML1_1.uri, ""); } catch (Exception e) { throw new RuntimeException("Failure adding test object: " + pid, e); } } private void removeTestObject(String pid) { try { admin.getAPIM().purgeObject(pid, "", false); } catch (Exception e) { throw new RuntimeException("Failure removing test object: " + pid, e); } } @Override public void tearDown() { restoreFedoraUsersFile(); deleteJunitPolicies(); reloadPolicies(); } public static void main(String[] args) { junit.textui.TestRunner.run(TestXACMLPolicies.class); } }