package org.cagrid.gts.service.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cagrid.core.common.FaultHelper;
import org.cagrid.gts.model.Permission;
import org.cagrid.gts.model.PermissionFilter;
import org.cagrid.gts.model.Role;
import org.cagrid.gts.service.exception.GTSInternalException;
import org.cagrid.gts.service.exception.IllegalPermissionException;
import org.cagrid.gts.service.exception.InvalidPermissionException;
import org.cagrid.gts.service.impl.db.DBManager;
import org.cagrid.gts.service.impl.db.PermissionsTable;
/**
* @author <A HREF="MAILTO:langella@bmi.osu.edu">Stephen Langella </A>
* @author <A HREF="MAILTO:oster@bmi.osu.edu">Scott Oster </A>
* @author <A HREF="MAILTO:hastings@bmi.osu.edu">Shannon Hastings </A>
* @version $Id: TrustedAuthorityManager.java,v 1.1 2006/03/08 19:48:46 langella Exp $
*/
public class PermissionManager {
private Log log;
private boolean dbBuilt = false;
private DBManager dbManager;
private Database db;
public PermissionManager(DBManager dbManager) {
log = LogFactory.getLog(this.getClass().getName());
this.dbManager = dbManager;
this.db = dbManager.getDatabase();
}
public synchronized void addPermission(Permission p) throws GTSInternalException, IllegalPermissionException {
// This method assumes that any Trusted Authorites associated with a
// permission is valid
this.buildDatabase();
if (p.getTrustedAuthorityName() == null) {
p.setTrustedAuthorityName(Constants.ALL_TRUST_AUTHORITIES);
}
if (p.getGridIdentity() == null) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class, "The permission " + formatPermission(p)
+ " no grid identity specified.");
throw fault;
}
if (p.getRole() == null) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class, "The permission " + formatPermission(p)
+ " no role specified.");
throw fault;
}
if ((p.getTrustedAuthorityName().equals(Constants.ALL_TRUST_AUTHORITIES)) && (!p.getRole().equals(Role.TRUST_SERVICE_ADMIN))) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class, "The permission " + formatPermission(p)
+ " must specify a specific Trust Authority.");
throw fault;
}
if ((!p.getTrustedAuthorityName().equals(Constants.ALL_TRUST_AUTHORITIES)) && (p.getRole().equals(Role.TRUST_SERVICE_ADMIN))) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class, "The permission " + formatPermission(p)
+ " cannot specify a specific Trust Authority.");
throw fault;
}
if (this.doesPermissionExist(p)) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class, "The permission " + formatPermission(p)
+ " cannot be added, it already exists.");
throw fault;
}
StringBuffer insert = new StringBuffer();
Connection c = null;
PreparedStatement s = null;
try {
insert.append("INSERT INTO " + PermissionsTable.TABLE_NAME + " SET " + PermissionsTable.GRID_IDENTITY + "= ?," + PermissionsTable.ROLE + "= ?,"
+ PermissionsTable.TRUSTED_AUTHORITY + "= ?");
c = db.getConnection();
s = c.prepareStatement(insert.toString());
s.setString(1, p.getGridIdentity());
s.setString(2, p.getRole().value());
s.setString(3, p.getTrustedAuthorityName());
s.execute();
s.close();
} catch (Exception e) {
this.log.error("Unexpected database error incurred in adding the permission " + formatPermission(p)
+ ", the following statement generated the error: \n" + insert.toString() + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error adding the permission "
+ formatPermission(p) + "!!!");
throw fault;
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
}
public synchronized void revokePermission(Permission p) throws GTSInternalException, InvalidPermissionException {
buildDatabase();
if (!doesPermissionExist(p)) {
InvalidPermissionException fault = FaultHelper.createFaultException(InvalidPermissionException.class, "Could not revoke " + formatPermission(p)
+ ", the permission does not exist!!!");
throw fault;
}
String sql = "delete from " + PermissionsTable.TABLE_NAME + " where " + PermissionsTable.GRID_IDENTITY + "= ? AND " + PermissionsTable.ROLE
+ "= ? AND " + PermissionsTable.TRUSTED_AUTHORITY + "= ?";
Connection c = null;
PreparedStatement s = null;
try {
c = db.getConnection();
s = c.prepareStatement(sql);
s.setString(1, p.getGridIdentity());
s.setString(2, p.getRole().value());
s.setString(3, p.getTrustedAuthorityName());
s.execute();
s.close();
} catch (Exception e) {
String perm = formatPermission(p);
this.log.error("Unexpected database error incurred in removing the permission " + perm + " exists, the following statement generated the error: \n"
+ sql + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error in removing the permission " + perm
+ " exists.");
throw fault;
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
}
public synchronized void revokePermissions(String trustedAuthorityName) throws GTSInternalException {
buildDatabase();
String sql = "delete from " + PermissionsTable.TABLE_NAME + " where " + PermissionsTable.TRUSTED_AUTHORITY + "= ?";
Connection c = null;
PreparedStatement s = null;
try {
c = db.getConnection();
s = c.prepareStatement(sql);
s.setString(1, trustedAuthorityName);
s.execute();
s.close();
} catch (Exception e) {
this.log.error("Unexpected database error incurred in removing the permissions for the trusted authority " + trustedAuthorityName + ".", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class,
"Unexpected database error incurred in removing the permissions for the trusted authority " + trustedAuthorityName + ".");
throw fault;
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
}
public synchronized boolean doesPermissionExist(Permission p) throws GTSInternalException {
String sql = "select count(*) from " + PermissionsTable.TABLE_NAME + " where " + PermissionsTable.GRID_IDENTITY + "= ? AND " + PermissionsTable.ROLE
+ "= ? AND " + PermissionsTable.TRUSTED_AUTHORITY + "= ?";
Connection c = null;
PreparedStatement s = null;
boolean exists = false;
try {
c = db.getConnection();
s = c.prepareStatement(sql);
s.setString(1, p.getGridIdentity());
s.setString(2, p.getRole().value());
s.setString(3, p.getTrustedAuthorityName());
ResultSet rs = s.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
if (count > 0) {
exists = true;
}
}
rs.close();
s.close();
} catch (Exception e) {
String perm = formatPermission(p);
this.log.error("Unexpected database error incurred in determining if the permission " + perm
+ " exists, the following statement generated the error: \n" + sql + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error in determining if the permission "
+ perm + " exists.");
throw fault;
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
return exists;
}
public boolean isUserTrustServiceAdmin(String gridIdentity) throws GTSInternalException {
this.buildDatabase();
Connection c = null;
PreparedStatement s = null ;
ResultSet rs = null;
boolean isAdmin = false;
StringBuffer sql = new StringBuffer();
sql.append("select count(*) from " + PermissionsTable.TABLE_NAME);
sql.append(" WHERE " + PermissionsTable.GRID_IDENTITY + " = ? AND ");
sql.append(PermissionsTable.ROLE + "='" + Role.TRUST_SERVICE_ADMIN.value() + "' AND ");
sql.append(PermissionsTable.TRUSTED_AUTHORITY + " = '" + Constants.ALL_TRUST_AUTHORITIES + "'");
try {
c = db.getConnection();
s = c.prepareStatement(sql.toString());
s.setString(1, gridIdentity);
rs = s.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
if (count > 0) {
isAdmin = true;
}
}
} catch (Exception e) {
this.log.error("Unexpected database error incurred in determining whether or not the user " + gridIdentity
+ " is a trust service administrator, the following statement generated the error: \n" + sql.toString() + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class,
"Unexpected error occurred in determining whether or not the user " + gridIdentity + " is a trust service administrator.");
throw fault;
} finally {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
return isAdmin;
}
public boolean isUserTrustedAuthorityAdmin(String authority, String gridIdentity) throws GTSInternalException {
this.buildDatabase();
Connection c = null;
PreparedStatement s = null;
ResultSet rs = null;
boolean isAdmin = false;
StringBuffer sql = new StringBuffer();
sql.append("select count(*) from " + PermissionsTable.TABLE_NAME);
sql.append(" WHERE " + PermissionsTable.GRID_IDENTITY + " = ?" + " AND ");
sql.append(PermissionsTable.ROLE + "='" + Role.TRUST_AUTHORITY_MANAGER.value() + "' AND ");
sql.append(PermissionsTable.TRUSTED_AUTHORITY + " = '" + authority + "'");
try {
c = db.getConnection();
s = c.prepareStatement(sql.toString());
s.setString(1, gridIdentity);
rs = s.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
if (count > 0) {
isAdmin = true;
}
}
} catch (Exception e) {
this.log.error("Unexpected database error incurred in determining whether or not the user " + gridIdentity
+ " is a trust service administrator, the following statement generated the error: \n" + sql.toString() + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class,
"Unexpected error occurred in determining whether or not the user " + gridIdentity + " is a trust service administrator.");
throw fault;
} finally {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
return isAdmin;
}
public synchronized Permission[] findPermissions(PermissionFilter filter) throws GTSInternalException {
this.buildDatabase();
Connection c = null;
PreparedStatement s = null;
ResultSet rs = null;
List<Permission> permissions = new ArrayList<Permission>();
StringBuffer sql = new StringBuffer();
try {
c = db.getConnection();
s = null;
if (filter != null) {
s = c.prepareStatement("select * from " + PermissionsTable.TABLE_NAME + " WHERE " + PermissionsTable.GRID_IDENTITY + " LIKE ? AND "
+ PermissionsTable.ROLE + " LIKE ? AND " + PermissionsTable.TRUSTED_AUTHORITY + " LIKE ?");
if (filter.getGridIdentity() != null) {
s.setString(1, "%" + filter.getGridIdentity() + "%");
} else {
s.setString(1, "%");
}
if (filter.getRole() != null) {
s.setString(2, "%" + filter.getRole().value() + "%");
} else {
s.setString(2, "%");
}
if (filter.getTrustedAuthorityName() != null) {
s.setString(3, "%" + filter.getTrustedAuthorityName() + "%");
} else {
s.setString(3, "%");
}
} else {
s = c.prepareStatement("select * from " + PermissionsTable.TABLE_NAME);
}
rs = s.executeQuery();
while (rs.next()) {
Permission p = new Permission();
p.setGridIdentity(rs.getString(PermissionsTable.GRID_IDENTITY));
p.setRole(Role.fromValue(rs.getString(PermissionsTable.ROLE)));
p.setTrustedAuthorityName(clean(rs.getString(PermissionsTable.TRUSTED_AUTHORITY)));
permissions.add(p);
}
Permission[] list = new Permission[permissions.size()];
for (int i = 0; i < list.length; i++) {
list[i] = (Permission) permissions.get(i);
}
return list;
} catch (Exception e) {
this.log.error(
"Unexpected database error incurred in finding permissions, the following statement generated the error: \n" + sql.toString() + "\n", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error occurred in finding permissions.");
throw fault;
} finally {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
if (s != null) {
try {
s.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
db.releaseConnection(c);
}
}
private String clean(String s) {
if ((s == null) || (s.trim().length() == 0)) {
return null;
} else {
return s;
}
}
private String formatPermission(Permission p) {
String role = null;
if (p.getRole() != null) {
role = p.getRole().value();
}
return "[" + p.getGridIdentity() + "," + role + "," + p.getTrustedAuthorityName() + "]";
}
public synchronized void buildDatabase() throws GTSInternalException {
if (!dbBuilt) {
try {
db.createDatabase();
if (!this.db.tableExists(PermissionsTable.TABLE_NAME)) {
String sql = this.dbManager.getPermissionsTable().getCreateTableSQL();
db.update(sql);
}
dbBuilt = true;
} catch (Exception e) {
this.log.error("Unexpected error in creating the database.", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error in creating the database.");
throw fault;
}
}
}
public synchronized void clearDatabase() throws GTSInternalException {
try {
buildDatabase();
db.update("delete FROM " + PermissionsTable.TABLE_NAME);
} catch (Exception e) {
this.log.error("Unexpected error in removing the database.", e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Unexpected error in removing the database.");
throw fault;
}
}
}