/* 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 org.fcrepo.test.api;
import static junit.framework.Assert.assertEquals;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathExists;
import static org.fcrepo.test.OneEmptyObjectTestSetup.ingestOneEmptyObject;
import static org.fcrepo.test.OneEmptyObjectTestSetup.purgeOneEmptyObject;
import java.util.HashMap;
import java.util.Map;
import junit.framework.JUnit4TestAdapter;
import org.custommonkey.xmlunit.NamespaceContext;
import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.fcrepo.client.FedoraClient;
import org.fcrepo.server.access.FedoraAPIAMTOM;
import org.fcrepo.server.management.FedoraAPIMMTOM;
import org.fcrepo.test.FedoraServerTestCase;
/**
* Tests correct/incorrect authentication against API-A/Lite and API-M/Lite.
* <p>
* These tests use basic authentication. To exercise the running server
* properly, it should be configured to require basic authentication on all
* interfaces.
* <p>
* By default, the tests will run against the "default" Fedora base URL, but
* this can be overridden by setting the "fedora.baseURL" system property.
*
* @author Chris Wilper
*/
public class TestAuthentication
extends FedoraServerTestCase {
private static final Logger LOGGER =
LoggerFactory.getLogger(TestAuthentication.class);
private final static String TEST_PID = "demo:AuthNTestObject";
private final static int TIMES_PER_TEST = 50;
private static FedoraClient CLIENT_VALID_USER_VALID_PASS;
private static FedoraClient CLIENT_VALID_USER_BOGUS_PASS;
private static FedoraClient CLIENT_BOGUS_USER;
//---
// API-M SOAP Tests
//---
@Test
public void testAPIMSOAPAuthNValidUserValidPass() throws Exception {
int failCount = modifyLabel(getClient(true, true), TIMES_PER_TEST);
assertEquals("Modifying object label using valid user, valid pass failed "
+ failCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
failCount);
}
@Test
public void testAPIMSOAPAuthNValidUserBogusPass() throws Exception {
int failCount = modifyLabel(getClient(true, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Modifying object label using valid user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
@Test
public void testAPIMSOAPAuthNBogusUser() throws Exception {
int failCount = modifyLabel(getClient(false, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Modifying object label using bogus user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
//---
// API-M Lite Tests
//---
@Test
public void testAPIMLiteAuthNValidUserValidPass() throws Exception {
int failCount = getNextPID(getClient(true, true), TIMES_PER_TEST);
assertEquals("Getting next PID using valid user, valid pass failed "
+ failCount + " times out of " + TIMES_PER_TEST
+ " attempts",
0,
failCount);
}
@Test
public void testAPIMLiteAuthNValidUserBogusPass() throws Exception {
int failCount = getNextPID(getClient(true, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Getting next PID using valid user, bogus pass succeeded "
+ successCount + " times out of " + TIMES_PER_TEST
+ " attempts", 0, successCount);
}
@Test
public void testAPIMLiteAuthNBogusUser() throws Exception {
int failCount = getNextPID(getClient(false, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Getting next PID using bogus user, bogus pass succeeded "
+ successCount + " times out of " + TIMES_PER_TEST
+ " attempts", 0, successCount);
}
//---
// API-A SOAP Tests
//---
@Test
public void testAPIASOAPAuthNValidUserValidPass() throws Exception {
int failCount = listDatastreams(getClient(true, true), TIMES_PER_TEST);
assertEquals("Listing object datastreams using valid user, valid pass failed "
+ failCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
failCount);
}
@Test
public void testAPIASOAPAuthNValidUserBogusPass() throws Exception {
int failCount = listDatastreams(getClient(true, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Listing object datastreams using valid user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
@Test
public void testAPIASOAPAuthNBogusUser() throws Exception {
int failCount =
listDatastreams(getClient(false, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Listing object datastreams using bogus user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
//---
// API-A Lite Tests
//---
@Test
public void testAPIALiteAuthNValidUserValidPass() throws Exception {
int failCount = getDCContent(getClient(true, true), TIMES_PER_TEST);
assertEquals("Getting DC content using valid user, valid pass failed "
+ failCount + " times out of " + TIMES_PER_TEST
+ " attempts",
0,
failCount);
}
@Test
public void testAPIALiteAuthNValidUserBogusPass() throws Exception {
int failCount = getDCContent(getClient(true, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Getting DC content using valid user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
@Test
public void testAPIALiteAuthNBogusUser() throws Exception {
int failCount = getDCContent(getClient(false, false), TIMES_PER_TEST);
int successCount = TIMES_PER_TEST - failCount;
assertEquals("Getting DC content using bogus user, bogus pass succeeded "
+ successCount
+ " times out of "
+ TIMES_PER_TEST
+ " attempts",
0,
successCount);
}
//---
// Static helpers
//---
@Before
public void setUp() throws Exception {
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("management", "http://www.fedora.info/definitions/1/0/management/");
nsMap.put("oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/");
NamespaceContext ctx = new SimpleNamespaceContext(nsMap);
XMLUnit.setXpathNamespaceContext(ctx);
}
@BeforeClass
public static void bootstrap() throws Exception {
CLIENT_VALID_USER_VALID_PASS = getFedoraClient();
ingestOneEmptyObject(CLIENT_VALID_USER_VALID_PASS, TEST_PID);
}
@AfterClass
public static void cleanUp() throws Exception {
XMLUnit.setXpathNamespaceContext(SimpleNamespaceContext.EMPTY_CONTEXT);
purgeOneEmptyObject(CLIENT_VALID_USER_VALID_PASS, TEST_PID);
if (CLIENT_VALID_USER_VALID_PASS != null) {
CLIENT_VALID_USER_VALID_PASS.shutdown();
}
if (CLIENT_VALID_USER_BOGUS_PASS != null) {
CLIENT_VALID_USER_BOGUS_PASS.shutdown();
}
if (CLIENT_BOGUS_USER != null) {
CLIENT_BOGUS_USER.shutdown();
}
}
private FedoraClient getClient(boolean validUser, boolean validPass)
throws Exception {
if (validUser) {
if (validPass) {
LOGGER.info("Using Fedora Client with valid user, valid pass");
if (CLIENT_VALID_USER_VALID_PASS == null) {
CLIENT_VALID_USER_VALID_PASS = getFedoraClient();
}
return CLIENT_VALID_USER_VALID_PASS;
} else {
LOGGER.info("Using Fedora Client with valid user, bogus pass");
if (CLIENT_VALID_USER_BOGUS_PASS == null) {
CLIENT_VALID_USER_BOGUS_PASS =
getFedoraClient(getBaseURL(),
getUsername(),
"bogus");
}
return CLIENT_VALID_USER_BOGUS_PASS;
}
} else {
LOGGER.info("Using Fedora Client with bogus user");
if (CLIENT_BOGUS_USER == null) {
CLIENT_BOGUS_USER =
getFedoraClient(getBaseURL(), "bogus", "bogus");
}
return CLIENT_BOGUS_USER;
}
}
//---
// Instance helpers
//---
// returns failCount
private int modifyLabel(FedoraClient client, int numTimes) {
LOGGER.info("Modifying object label via API-M SOAP {} times...",
numTimes);
int failCount = 0;
FedoraAPIMMTOM apim = null;
for (int i = 0; i < numTimes; i++) {
try {
if (apim == null) {
apim = client.getAPIMMTOM();
}
apim.modifyObject(TEST_PID, null, null, null, "i=" + i);
} catch (Exception e) {
failCount++;
}
}
LOGGER.info("Failed {} times", failCount);
return failCount;
}
// returns failCount
private int getNextPID(FedoraClient client, int numTimes) {
LOGGER.info("Getting next PID via API-M Lite {} times...", numTimes);
int failCount = 0;
for (int i = 0; i < numTimes; i++) {
try {
Document result =
getXMLQueryResult(client,
"/management/getNextPID?xml=true");
assertXpathEvaluatesTo("1", "count(//management:pid)", result);
} catch (Exception e) {
failCount++;
}
}
LOGGER.info("Failed {} times", failCount);
return failCount;
}
// returns failCount
private int listDatastreams(FedoraClient client, int numTimes) {
LOGGER.info("Listing object datastreams via API-A SOAP {} times...", numTimes);
int failCount = 0;
FedoraAPIAMTOM apia = null;
for (int i = 0; i < numTimes; i++) {
try {
if (apia == null) {
apia = client.getAPIAMTOM();
}
apia.listDatastreams(TEST_PID, null);
} catch (Exception e) {
failCount++;
}
}
LOGGER.info("Failed {} times", failCount);
return failCount;
}
// returns failCount
private int getDCContent(FedoraClient client, int numTimes) {
LOGGER.debug("Getting DC content via API-A Lite {} times...", numTimes);
int failCount = 0;
for (int i = 0; i < numTimes; i++) {
try {
Document result =
getXMLQueryResult(client, "/get/" + TEST_PID + "/DC");
assertXpathExists("/oai_dc:dc", result);
} catch (Exception e) {
LOGGER.info(e.getMessage());
failCount++;
}
}
LOGGER.debug("Failed {} times", failCount);
return failCount;
}
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(TestAuthentication.class);
}
public static void main(String[] args) {
JUnitCore.runClasses(TestAuthentication.class);
}
}