package org.jboss.security.auth.spi;
import java.util.Properties;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.acl.Group;
import java.security.Principal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.security.auth.login.LoginException;
import javax.security.auth.login.FailedLoginException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.jboss.logging.Logger;
import org.jboss.security.SimpleGroup;
public class Util
{
static Group[] getRoleSets(String targetUser, Properties roles,
char roleGroupSeperator, AbstractServerLoginModule aslm)
{
Enumeration users = roles.propertyNames();
SimpleGroup rolesGroup = new SimpleGroup("Roles");
ArrayList groups = new ArrayList();
groups.add(rolesGroup);
while (users.hasMoreElements() && targetUser != null)
{
String user = (String) users.nextElement();
String value = roles.getProperty(user);
int index = user.indexOf(roleGroupSeperator);
boolean isRoleGroup = false;
boolean userMatch = false;
if (index > 0 && targetUser.regionMatches(0, user, 0, index) == true)
isRoleGroup = true;
else
userMatch = targetUser.equals(user);
if (isRoleGroup == true)
{
String groupName = user.substring(index + 1);
if (groupName.equals("Roles"))
parseGroupMembers(rolesGroup, value, aslm);
else
{
SimpleGroup group = new SimpleGroup(groupName);
parseGroupMembers(group, value, aslm);
groups.add(group);
}
}
else if (userMatch == true)
{
parseGroupMembers(rolesGroup, value, aslm);
}
}
Group[] roleSets = new Group[groups.size()];
groups.toArray(roleSets);
return roleSets;
}
static Group[] getRoleSets(String username, String dsJndiName,
String rolesQuery, AbstractServerLoginModule aslm)
throws LoginException
{
Connection conn = null;
HashMap setsMap = new HashMap();
PreparedStatement ps = null;
ResultSet rs = null;
try
{
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(dsJndiName);
conn = ds.getConnection();
ps = conn.prepareStatement(rolesQuery);
try
{
ps.setString(1, username);
}
catch(ArrayIndexOutOfBoundsException ignore)
{
}
rs = ps.executeQuery();
if( rs.next() == false )
{
if( aslm.getUnauthenticatedIdentity() == null )
throw new FailedLoginException("No matching username found in Roles");
Group[] roleSets = { new SimpleGroup("Roles") };
return roleSets;
}
do
{
String name = rs.getString(1);
String groupName = rs.getString(2);
if( groupName == null || groupName.length() == 0 )
groupName = "Roles";
Group group = (Group) setsMap.get(groupName);
if( group == null )
{
group = new SimpleGroup(groupName);
setsMap.put(groupName, group);
}
try
{
Principal p = aslm.createIdentity(name);
aslm.log.trace("Assign user to role " + name);
group.addMember(p);
}
catch(Exception e)
{
aslm.log.debug("Failed to create principal: "+name, e);
}
} while( rs.next() );
}
catch(NamingException ex)
{
throw new LoginException(ex.toString(true));
}
catch(SQLException ex)
{
aslm.log.error("SQL failure", ex);
throw new LoginException(ex.toString());
}
finally
{
if( rs != null )
{
try
{
rs.close();
}
catch(SQLException e)
{}
}
if( ps != null )
{
try
{
ps.close();
}
catch(SQLException e)
{}
}
if( conn != null )
{
try
{
conn.close();
}
catch (Exception ex)
{}
}
}
Group[] roleSets = new Group[setsMap.size()];
setsMap.values().toArray(roleSets);
return roleSets;
}
static Properties loadProperties(String defaultsName, String propertiesName, Logger log)
throws IOException
{
Properties bundle = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL defaultUrl = null;
URL url = null;
if( loader instanceof URLClassLoader )
{
URLClassLoader ucl = (URLClassLoader) loader;
defaultUrl = ucl.findResource(defaultsName);
url = ucl.findResource(propertiesName);
log.trace("findResource: "+url);
}
if( defaultUrl == null )
defaultUrl = loader.getResource(defaultsName);
if( url == null )
url = loader.getResource(propertiesName);
if( url == null && defaultUrl == null )
{
String msg = "No properties file: " + propertiesName
+ " or defaults: " +defaultsName+ " found";
throw new IOException(msg);
}
log.trace("Properties file=" + url+", defaults="+defaultUrl);
Properties defaults = new Properties();
if( defaultUrl != null )
{
try
{
InputStream is = defaultUrl.openStream();
defaults.load(is);
is.close();
log.debug("Loaded defaults, users="+defaults.keySet());
}
catch(Throwable e)
{
log.debug("Failed to load defaults", e);
}
}
bundle = new Properties(defaults);
if( url != null )
{
InputStream is = url.openStream();
if (is != null)
{
bundle.load(is);
is.close();
}
else
{
throw new IOException("Properties file " + propertiesName + " not avilable");
}
log.debug("Loaded properties, users="+bundle.keySet());
}
return bundle;
}
static void parseGroupMembers(Group group, String roles,
AbstractServerLoginModule aslm)
{
StringTokenizer tokenizer = new StringTokenizer(roles, ",");
while (tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
try
{
Principal p = aslm.createIdentity(token);
group.addMember(p);
}
catch (Exception e)
{
aslm.log.warn("Failed to create principal for: "+token, e);
}
}
}
}