package org.cagrid.cds.service.impl.policy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cagrid.cds.model.AllowedParties; import org.cagrid.cds.model.DelegationIdentifier; import org.cagrid.cds.model.DelegationPolicy; import org.cagrid.cds.model.IdentityDelegationPolicy; 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.tools.database.Database; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class IdentityPolicyHandler implements PolicyHandler { private final static String TABLE = "identity_policies"; private final static String DELEGATION_ID = "delegation_id"; private final static String GRID_IDENTITY = "grid_identity"; private boolean dbBuilt = false; private Database db; private Log log; public IdentityPolicyHandler(Database db) { this.log = LogFactory.getLog(this.getClass().getName()); this.db = db; } 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 DelegationPolicy getPolicy(DelegationIdentifier id) throws CDSInternalException, InvalidPolicyException { if (policyExists(id)) { List<String> parties = new ArrayList<String>(); Connection c = null; try { c = this.db.getConnection(); PreparedStatement s = c.prepareStatement("select " + GRID_IDENTITY + " from " + TABLE + " WHERE " + DELEGATION_ID + "= ? "); s.setLong(1, id.getDelegationId()); ResultSet rs = s.executeQuery(); while (rs.next()) { parties.add(rs.getString(1)); } rs.close(); s.close(); IdentityDelegationPolicy policy = new IdentityDelegationPolicy(); AllowedParties ap = new AllowedParties(); ap.getGridIdentity().addAll(parties); policy.setAllowedParties(ap); 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 { boolean isAuthorized = false; Connection c = null; try { c = this.db.getConnection(); PreparedStatement s = c.prepareStatement("select count(*) " + " from " + TABLE + " WHERE " + DELEGATION_ID + "= ? AND " + GRID_IDENTITY + "= ?"); s.setLong(1, id.getDelegationId()); s.setString(2, gridIdentity); ResultSet rs = s.executeQuery(); if (rs.next()) { int count = rs.getInt(1); if (count > 0) { isAuthorized = true; } } rs.close(); s.close(); } catch (Exception e) { log.error(e.getMessage(), e); throw Errors.makeException(CDSInternalException.class, "Unexpected Database Error.", e); } finally { this.db.releaseConnection(c); } return isAuthorized; } 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()); } IdentityDelegationPolicy policy = (IdentityDelegationPolicy) pol; Connection c = null; boolean policyStored = false; try { c = this.db.getConnection(); AllowedParties ap = policy.getAllowedParties(); if (ap != null) { for (String party : ap.getGridIdentity()) { PreparedStatement s = c.prepareStatement("INSERT INTO " + TABLE + " SET " + DELEGATION_ID + "= ?, " + GRID_IDENTITY + "= ?"); s.setLong(1, id.getDelegationId()); s.setString(2, party); s.execute(); s.close(); policyStored = true; } } } 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); } if (!policyStored) { throw Errors.makeException(InvalidPolicyException.class, "No allowed parties provided."); } } 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 boolean isSupported(String policyClassName) { if (policyClassName.equals(IdentityDelegationPolicy.class.getName())) { return true; } else if (policyClassName.equals("org.cagrid.gaards.cds.common.IdentityDelegationPolicy")) { // LEGACY SUPPORT return true; } else { return false; } } 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); } } private void buildDatabase() throws CDSInternalException { if (!dbBuilt) { try { if (!this.db.tableExists(TABLE)) { String table = "CREATE TABLE " + TABLE + " (" + DELEGATION_ID + " BIGINT NOT NULL," + GRID_IDENTITY + " 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); } } } }