package org.cagrid.cds.service.impl.policy; import gov.nih.nci.cagrid.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cagrid.cds.model.DelegationIdentifier; import org.cagrid.cds.model.DelegationPolicy; import org.cagrid.cds.model.GroupDelegationPolicy; import org.cagrid.cds.service.exception.CDSInternalException; import org.cagrid.cds.service.exception.InvalidPolicyException; import org.cagrid.cds.service.impl.util.Errors; import org.cagrid.gridgrouper.client.GridGrouperClient; import org.cagrid.tools.database.Database; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class GroupPolicyHandler implements PolicyHandler { private final static String TABLE = "group_policies"; private final static String DELEGATION_ID = "delegation_id"; private final static String GRID_GROUPER_URL = "grid_grouper_url"; private final static String GROUP_SYSTEM_NAME = "group_name"; private boolean dbBuilt = false; private Database db; private Log log; private GridGrouperClient grouper; public GroupPolicyHandler(Database db, GridGrouperClient grouper) { this.log = LogFactory.getLog(this.getClass().getName()); this.db = db; this.grouper = grouper; } public boolean policyExists(DelegationIdentifier id) throws CDSInternalException { buildDatabase(); try { return db.exists(TABLE, DELEGATION_ID, id.getDelegationId()); } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } } public DelegationPolicy getPolicy(DelegationIdentifier id) throws CDSInternalException, InvalidPolicyException { if (policyExists(id)) { Connection c = null; try { GroupDelegationPolicy policy = new GroupDelegationPolicy(); c = this.db.getConnection(); PreparedStatement s = c.prepareStatement("select * from " + TABLE + " WHERE " + DELEGATION_ID + "= ? "); s.setLong(1, id.getDelegationId()); ResultSet rs = s.executeQuery(); if (rs.next()) { policy.setGridGrouperServiceURL(rs .getString(GRID_GROUPER_URL)); policy.setGroupName(rs.getString(GROUP_SYSTEM_NAME)); } rs.close(); s.close(); return policy; } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } finally { this.db.releaseConnection(c); } } else { throw Errors.makeException(InvalidPolicyException.class, "The requested policy does not exist."); } } public boolean isAuthorized(DelegationIdentifier id, String gridIdentity) throws CDSInternalException { try { GroupDelegationPolicy policy = (GroupDelegationPolicy) getPolicy(id); if(log.isDebugEnabled()){ log.debug("Checking to determine if "+gridIdentity+" is a member of "+policy.getGroupName()+" ("+policy.getGridGrouperServiceURL()+")."); } boolean isMember = grouper.isMemberOf(gridIdentity, policy.getGroupName()); if(log.isDebugEnabled()){ String member = "IS A MEMBER"; if(!isMember){ member = "IS NOT A MEMBER"; } log.debug(gridIdentity+" "+member+" of "+policy.getGroupName()+" ("+policy.getGridGrouperServiceURL()+")."); } return isMember; } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Error.", e); } } public boolean isSupported(String policyClassName) { if (policyClassName.equals(GroupDelegationPolicy.class.getName())) { return true; } else if (policyClassName.equals("org.cagrid.gaards.cds.common.GroupDelegationPolicy")) { //LEGACY SUPPORT return true; } else { return false; } } public void removeAllStoredPolicies() throws CDSInternalException { buildDatabase(); try { this.db.update("DELETE FROM " + TABLE); dbBuilt = false; } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } } public void removePolicy(DelegationIdentifier id) throws CDSInternalException { buildDatabase(); Connection c = null; try { c = this.db.getConnection(); PreparedStatement s = c.prepareStatement("DELETE FROM " + TABLE + " WHERE " + DELEGATION_ID + "= ?"); s.setLong(1, id.getDelegationId()); s.execute(); s.close(); } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } finally { this.db.releaseConnection(c); } } public void storePolicy(DelegationIdentifier id, DelegationPolicy pol) throws CDSInternalException, InvalidPolicyException { this.buildDatabase(); if (!isSupported(pol.getClass().getName())) { throw Errors.makeException(InvalidPolicyException.class, "The policy handler " + getClass().getName() + " does not support the policy " + pol.getClass().getName() + "."); } if (this.policyExists(id)) { throw Errors.makeException(InvalidPolicyException.class, "A policy already exists for the delegation " + id.getDelegationId()); } GroupDelegationPolicy policy = (GroupDelegationPolicy) pol; if (Utils.clean(policy.getGridGrouperServiceURL()) == null) { throw Errors.makeException(InvalidPolicyException.class, "Invalid Grid Grouper Service URL specified."); } if (Utils.clean(policy.getGroupName()) == null) { throw Errors.makeException(InvalidPolicyException.class, "Invalid Group Name specified."); } try { grouper.getGroup(policy.getGroupName()); } catch (Exception e) { throw Errors.makeException(InvalidPolicyException.class, "Could not resolve the group " + policy.getGroupName() + " on the Grid Grouper " + policy.getGridGrouperServiceURL() + ".", e); } Connection c = null; try { c = this.db.getConnection(); PreparedStatement s = c.prepareStatement("INSERT INTO " + TABLE + " SET " + DELEGATION_ID + "= ?, " + GRID_GROUPER_URL + "= ?," + GROUP_SYSTEM_NAME + "= ?"); s.setLong(1, id.getDelegationId()); s.setString(2, policy.getGridGrouperServiceURL()); s.setString(3, policy.getGroupName()); s.execute(); s.close(); } catch (Exception e) { try { this.removePolicy(id); } catch (Exception ex) { } log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } finally { this.db.releaseConnection(c); } } private void buildDatabase() throws CDSInternalException { if (!dbBuilt) { try { if (!this.db.tableExists(TABLE)) { String table = "CREATE TABLE " + TABLE + " (" + DELEGATION_ID + " BIGINT NOT NULL," + GRID_GROUPER_URL + " VARCHAR(255) NOT NULL," + GROUP_SYSTEM_NAME + " VARCHAR(255) NOT NULL, INDEX document_index (" + DELEGATION_ID + "));"; this.db.update(table); } dbBuilt = true; } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } } } }