package org.exist.security;
import org.exist.storage.DBBroker;
import org.exist.xmldb.DatabaseInstanceManager;
import org.exist.xmldb.UserManagementService;
import org.exist.StandaloneServer;
import org.junit.*;
import static org.junit.Assert.*;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.Resource;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.CollectionManagementService;
import org.mortbay.util.MultiException;
import java.util.LinkedList;
import java.util.Iterator;
import java.net.BindException;
@RunWith (Parameterized.class)
public class XMLDBSecurityTest {
private static String DB_DRIVER = "org.exist.xmldb.DatabaseImpl";
private String baseUri;
private static StandaloneServer server;
public XMLDBSecurityTest(String baseUri) {
this.baseUri = baseUri;
}
@Parameterized.Parameters
public static LinkedList<String[]> instances() {
LinkedList<String[]> params = new LinkedList<String[]>();
params.add(new String[] { "xmldb:exist://" });
params.add(new String[] { "xmldb:exist://localhost:8088/xmlrpc" });
return params;
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldCreateCollection() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
CollectionManagementService cms = (CollectionManagementService)
test.getService("CollectionManagementService", "1.0");
cms.createCollection("createdByGuest");
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldAddResource() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
Resource resource = test.createResource("createdByGuest", "XMLResource");
resource.setContent("<testMe/>");
test.storeResource(resource);
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldRemoveCollection() throws XMLDBException {
Collection root = DatabaseManager.getCollection(baseUri + "/db", "guest", "guest");
CollectionManagementService cms = (CollectionManagementService)
root.getService("CollectionManagementService", "1.0");
cms.removeCollection("securityTest1");
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldChmodCollection() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
ums.chmod(0777);
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldChmodResource() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
Resource resource = test.getResource("test.xml");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
ums.chmod(resource, 0777);
}
@Test (expected=XMLDBException.class) // fails since guest has no write permissions
public void worldChownCollection() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
User guest = ums.getUser("guest");
// make myself the owner ;-)
ums.chown(guest, "guest");
}
@Test (expected=XMLDBException.class)
// only the owner or admin can chown a collection or resource
public void worldChownResource() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "guest", "guest");
Resource resource = test.getResource("test.xml");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
User test2 = ums.getUser("guest");
ums.chown(resource, test2, "guest");
}
@Test
public void groupCreateSubColl() {
try {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
CollectionManagementService cms = (CollectionManagementService)
test.getService("CollectionManagementService", "1.0");
Collection newCol = cms.createCollection("createdByTest2");
assertNotNull(newCol);
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@Test
public void groupCreateResource() {
try {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
CollectionManagementService cms = (CollectionManagementService)
test.getService("CollectionManagementService", "1.0");
Resource resource = test.createResource("createdByTest2.xml", "XMLResource");
resource.setContent("<testMe/>");
test.storeResource(resource);
resource = test.getResource("createdByTest2.xml");
assertNotNull(resource);
assertEquals("<testMe/>", resource.getContent().toString());
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@Test
public void groupRemoveCollection() {
try {
Collection root = DatabaseManager.getCollection(baseUri + "/db", "test2", "test2");
CollectionManagementService cms = (CollectionManagementService)
root.getService("CollectionManagementService", "1.0");
cms.removeCollection("securityTest1");
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@Test
public void groupChmodCollection() {
try {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
ums.chmod(0777);
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@Test
public void groupChmodResource() {
try {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
Resource resource = test.getResource("test.xml");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
ums.chmod(resource, 0777);
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@Test (expected=XMLDBException.class)
// only the owner or admin can chown a collection or resource
public void groupChownCollection() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
User test2 = ums.getUser("test2");
ums.chown(test2, "users");
Permission perms = ums.getPermissions(test);
assertEquals("test2", perms.getOwner());
}
@Test (expected=XMLDBException.class)
// only the owner or admin can chown a collection or resource
public void groupChownResource() throws XMLDBException {
Collection test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test2", "test2");
Resource resource = test.getResource("test.xml");
UserManagementService ums = (UserManagementService)
test.getService("UserManagementService", "1.0");
// grant myself all rights ;-)
User test2 = ums.getUser("test2");
ums.chown(resource, test2, "users");
}
@Before
public void setup() {
try {
Collection root = DatabaseManager.getCollection(baseUri + "/db", "admin", null);
UserManagementService ums = (UserManagementService) root.getService("UserManagementService", "1.0");
User user = new User("test1", "test1", "users");
ums.addUser(user);
user = new User("test2", "test2", "users");
ums.addUser(user);
// create a collection /db/securityTest as user "test1"
CollectionManagementService cms = (CollectionManagementService)
root.getService("CollectionManagementService", "1.0");
Collection test = cms.createCollection("securityTest1");
ums = (UserManagementService) test.getService("UserManagementService", "1.0");
// pass ownership to test1
User test1 = ums.getUser("test1");
ums.chown(test1, "users");
// full permissions for user and group, none for world
ums.chmod(0770);
test = DatabaseManager.getCollection(baseUri + "/db/securityTest1", "test1", "test1");
Resource resource = test.createResource("test.xml", "XMLResource");
resource.setContent("<test/>");
test.storeResource(resource);
ums.chmod(resource, 0770);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@After
public void cleanup() {
try {
Collection root = DatabaseManager.getCollection(baseUri + "/db", "admin", null);
CollectionManagementService cms =
(CollectionManagementService) root.getService("CollectionManagementService", "1.0");
if (root.getChildCollection("securityTest1") != null)
cms.removeCollection("securityTest1");
UserManagementService ums = (UserManagementService) root.getService("UserManagementService", "1.0");
User test1 = ums.getUser("test1");
ums.removeUser(test1);
User test2 = ums.getUser("test2");
ums.removeUser(test2);
} catch (XMLDBException e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@BeforeClass
public static void startServer() {
try {
Class cl = Class.forName(DB_DRIVER);
Database database = (Database) cl.newInstance();
database.setProperty("create-database", "true");
DatabaseManager.registerDatabase(database);
Collection root = DatabaseManager.getCollection("xmldb:exist:///db", "admin", null);
assertNotNull(root);
server = new StandaloneServer();
if (!server.isStarted()) {
try {
System.out.println("Starting standalone server...");
String[] args = {};
server.run(args);
while (!server.isStarted()) {
Thread.sleep(1000);
}
} catch (MultiException e) {
boolean rethrow = true;
Iterator i = e.getExceptions().iterator();
while (i.hasNext()) {
Exception e0 = (Exception)i.next();
if (e0 instanceof BindException) {
System.out.println("A server is running already !");
rethrow = false;
break;
}
}
if (rethrow) throw e;
}
}
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@AfterClass
public static void stopServer() {
try {
Collection root = DatabaseManager.getCollection("xmldb:exist:///db", "admin", null);
DatabaseInstanceManager mgr =
(DatabaseInstanceManager) root.getService("DatabaseInstanceManager", "1.0");
mgr.shutdown();
} catch (XMLDBException e) {
e.printStackTrace();
}
server.shutdown();
server = null;
}
}