/*
* $Date: 2007/05/17 17:00:00 $
* Marcus Ziegelmeier - Diplomarbeit
*/
package org.securityfilter.exist.realm.catalina;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Realm;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.*;
import java.util.ArrayList;
import java.util.List;
import org.exist.EXistException;
import org.exist.security.SecurityManager;
import org.exist.security.User;
import org.exist.security.XmldbPrincipal;
import org.exist.security.MD5;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.util.Configuration;
import org.exist.util.DatabaseConfigurationException;
import org.exist.xmldb.UserManagementService;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.XMLDBException;
/**
* ExistCatalinaRealm - Catalina Realm implementation to demonstrate
* org.securityfilter.realm.catalina.CatalinaRealmAdapter adapter class.
*
*/
public class ExistCatalinaRealm extends RealmBase {
/**
* private String basedir = ".";
* private String configuration = "exist-conf.xml";
* private String uri = "xmldb:exist://" + DBBroker.ROOT_COLLECTION;
* private String driver = "org.exist.xmldb.DatabaseImpl";
*/
private String basedir;
private String configuration;
private String uri;
private String driver;
private UserManagementService service = null;
private User defaultUser = null;
/**
* Descriptive information about this Realm implementation.
*/
protected final String info = "XMLDBRealm/1.0";
/**
* Descriptive information about this Realm implementation.
*/
protected static final String name = "XMLDBRealm";
/**
* Return descriptive information about this Realm implementation and the
* corresponding version number, in the format <description>/<version>.
*/
public String getInfo() {
return info;
}
/**
* Return a short name for this Realm implementation.
*/
protected String getName() {
return name;
}
/**
* Return the Principal associated with the given user name.
*/
protected Principal getPrincipal(String username) {
User user = null;
try {
user = service.getUser(username);
System.out.println("user = \'" + user + "\'");
} catch (XMLDBException e) {
}
if (user == null) {
user = defaultUser;
}
// Accumulate the list of roles for this user
ArrayList list = new ArrayList();
String[] groups = user.getGroups();
for (int i = 0; i < groups.length; i++) {
list.add(groups[i]);
System.out.println("users-group = \'" + groups[i] + "\'");
}
// return (Principal) new DefaultXmldbPrinciple(this, username, user.getPassword(), list);
Principal userPrincipal = new GenericPrincipal(this, username, user.getPassword(), list);
System.out.println("userPrincipal = \'" + userPrincipal + "\'");
return userPrincipal;
}
protected class DefaultXmldbPrinciple extends GenericPrincipal implements XmldbPrincipal {
public DefaultXmldbPrinciple(Realm arg0, String arg1, String arg2, List arg3) {
super(arg0, arg1, arg2, arg3);
}
}
/**
* Return the Principal associated with the specified username and
* credentials, if there is one; otherwise return null.
*
* @param username
* Username of the Principal to look up
* @param credentials
* Password or other credentials to use in authenticating this
* username
*/
public MD5 validation;
public Principal authenticate(String username, String credentials) {
GenericPrincipal principal = (GenericPrincipal) getPrincipal(username);
validation = new MD5();
String md5_valid = validation.md(credentials,true);
System.out.println("MD5-Exist-new = \'" + md5_valid + "\'");
boolean validated = false;
if (principal != null) {
if (hasMessageDigest()) {
// Hex hashes should be compared case-insensitive
validated = (md5_valid.equalsIgnoreCase(principal.getPassword()));
System.out.println("validated = \'" + validated + "\'");
} else {
validated = (md5_valid.equals(principal.getPassword()));
System.out.println("validated = \'" + validated + "\'");
}
}
if (validated) {
System.out.println("userDatabaseRealm.authenticateSuccess = \'" + username + "\'");
return (principal);
} else {
System.out.println("userDatabaseRealm.authenticateFailure = \'" + username + "\'");
return (null);
}
}
/**
* Return the password associated with the given principal's user name.
*/
protected String getPassword(String username) {
GenericPrincipal principal = (GenericPrincipal) getPrincipal(username);
if (principal != null) {
return (principal.getPassword());
} else {
return (null);
}
}
/**
* Prepare for active use of the public methods of this Component.
*
* @exception LifecycleException
* if this component detects a fatal error that prevents it
* from being started
*/
public synchronized void start() throws LifecycleException {
try {
URI existURI = new URI(uri);
System.out.println("existURI = \'" + existURI + "\'");
System.out.println("existURI.getHost() = \'" + existURI.getHost() + "\'");
System.out.println("ROOT_COLLECTION = \'" + DBBroker.ROOT_COLLECTION + "\'");
System.out.println("SYSTEM_COLLECTION = \'" + DBBroker.SYSTEM_COLLECTION + "\'");
if("".equals(existURI.getHost()) || existURI.getHost() == null){
this.startExistDb();
}
String driver = "org.exist.xmldb.DatabaseImpl";
Class cl = Class.forName(driver);
System.out.println("Databasedriver = \'" + cl + "\'");
DatabaseManager dbManager = new DatabaseManager();
dbManager.registerDatabase((Database) cl.newInstance());
// try to get collection
Collection collection = DatabaseManager.getCollection(uri);
System.out.println("collection = \'" + collection + "\'");
if (collection == null) {
throw new LifecycleException("unable to resolve");
}
service = (UserManagementService) collection.getService("UserManagementService", "1.0");
System.out.println("service = \'" + service + "\'");
if (service == null) {
throw new LifecycleException("UserManagementService not found");
}
defaultUser = service.getUser(SecurityManager.GUEST_USER);
System.out.println("defaultUser = \'" + defaultUser + "\'");
if (defaultUser == null) {
throw new LifecycleException("defaultUser not found");
}
/* initialize security */
boolean admin = true;
if(admin){
User adminUser = service.getUser(SecurityManager.DBA_USER);
System.out.println("adminUser = \'" + adminUser + "\'");
if(adminUser.getPassword() == null){
adminUser.setPassword("admin");
log("Update Admin User on inital start");
}
}
} catch (ClassNotFoundException e) {
throw new LifecycleException(e.getMessage(),e);
} catch (XMLDBException e) {
throw new LifecycleException(e.getMessage(),e);
} catch (InstantiationException e) {
throw new LifecycleException(e.getMessage(),e);
} catch (IllegalAccessException e) {
throw new LifecycleException(e.getMessage(),e);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Perform normal superclass initialization
super.start();
}
/* (non-Javadoc)
* @see org.apache.catalina.Lifecycle#stop()
*/
public void stop() throws LifecycleException {
super.stop();
BrokerPool.stopAll(false);
}
public synchronized void startExistDb() throws LifecycleException {
try {
if (!BrokerPool.isConfigured()) {
this.log("Starting Database");
this.log("exist.home=" + basedir);
File f = new File(basedir + File.separator + configuration);
this.log("reading configuration from " + f.getAbsolutePath());
if (!f.canRead())
throw new LifecycleException("configuration file "
+ configuration + " not found or not readable");
Configuration conf = new Configuration(configuration, basedir);
this.log("Configuration" + conf);
BrokerPool.configure(1, 5, conf);
}
} catch (EXistException e) {
throw new LifecycleException(e.getMessage(),e);
} catch (DatabaseConfigurationException e) {
throw new LifecycleException(e.getMessage(),e);
}
}
/**
* @return Returns the basedir.
*/
public String getBasedir() {
return basedir;
}
/**
* @param basedir The basedir to set.
*/
public void setBasedir(String basedir) {
this.basedir = basedir;
System.out.println(this.getClass().getName() + ": basedir = \'" + basedir + "\'");
}
/**
* @return Returns the configuration.
*/
public String getConfiguration() {
return configuration;
}
/**
* @param configuration The configuration to set.
*/
public void setConfiguration(String configuration) {
this.configuration = configuration;
System.out.println(this.getClass().getName() + ": configuration = \'" + configuration + "\'");
}
/**
* @return Returns the driver.
*/
public String getDriver() {
return driver;
}
/**
* @param driver The driver to set.
*/
public void setDriver(String driver) {
this.driver = driver;
System.out.println(this.getClass().getName() + ": driver = \'" + driver + "\'");
}
/**
* @return Returns the uri.
*/
public String getUri() {
return uri;
}
/**
* @param uri The uri to set.
*/
public void setUri(String uri) {
this.uri = uri;
System.out.println(this.getClass().getName() + ": uri = \'" + uri + "\'");
}
private String exampleProperty;
/**
* Setter for exampleProperty to deomonstrate setting realm properties from config file.
*
* This has no effect other than printing a message when the property is set.
*
* @param value example property value
*/
public void setExampleProperty(String value) {
exampleProperty = value;
System.out.println(this.getClass().getName() + ": exampleProperty set to \'" + value + "\'");
}
/**
* Getter for exampleProperty.
*
* @return the value of exampleProperty
*/
public String getExampleProperty() {
return exampleProperty;
}
}
// ----------------------------------------------------------------------------
// EOF