X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=ONAP-PAP-REST%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Fpap%2Fxacml%2Frest%2Fcomponents%2FPolicyDBDao.java;h=7591781ffb57afe8ee1a05953bb488e9be54e563;hb=b6bae924c4a794cd772ac1524089fc8739e310b1;hp=876e87580d0b7b0406c736473e5354ddd76c5271;hpb=490459f7fe922c8448e8a38b87fd48e5e71d7b4c;p=policy%2Fengine.git diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java index 876e87580..7591781ff 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java @@ -28,16 +28,20 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; +import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.InvalidKeyException; import java.security.Key; +import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Date; import java.util.HashMap; @@ -49,7 +53,10 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import javax.crypto.BadPaddingException; import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; @@ -62,6 +69,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.onap.policy.common.logging.eelf.MessageCodes; @@ -71,6 +79,7 @@ import org.onap.policy.common.logging.flexlogger.Logger; import org.onap.policy.pap.xacml.rest.XACMLPapServlet; import org.onap.policy.rest.XACMLRestProperties; import org.onap.policy.rest.adapter.PolicyRestAdapter; +import org.onap.policy.rest.dao.PolicyDBException; import org.onap.policy.rest.jpa.ActionBodyEntity; import org.onap.policy.rest.jpa.ConfigurationDataEntity; import org.onap.policy.rest.jpa.DatabaseLockEntity; @@ -84,6 +93,7 @@ import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.api.pap.PAPPolicyEngine; import org.onap.policy.xacml.std.pap.StdPDPGroup; import org.onap.policy.xacml.std.pap.StdPDPPolicy; +import org.onap.policy.xacml.util.XACMLPolicyScanner; import org.onap.policy.xacml.util.XACMLPolicyWriter; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -115,7 +125,7 @@ public class PolicyDBDao { * @return The new instance of PolicyDBDao or throw exception if the given emf is null. * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this. */ - public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) throws Exception{ + public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf){ logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called"); if(currentInstance == null){ if(emf != null){ @@ -132,7 +142,7 @@ public class PolicyDBDao { * @return The instance of PolicyDBDao or throws exception if the given instance is null. * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this. */ - public static PolicyDBDao getPolicyDBDaoInstance() throws Exception{ + public static PolicyDBDao getPolicyDBDaoInstance(){ logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called"); if(currentInstance != null){ return currentInstance; @@ -324,15 +334,15 @@ public class PolicyDBDao { return urlUserPass; } - private static String encryptPassword(String password) throws Exception{ + private static String encryptPassword(String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, aesKey()); byte[] encryption = cipher.doFinal(password.getBytes("UTF-8")); - System.out.println(encryption); + logger.debug("Encryption value is " + encryption); return new String(Base64.getMimeEncoder().encode(encryption),"UTF-8"); } - private static String decryptPassword(String encryptedPassword) throws Exception{ + private static String decryptPassword(String encryptedPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{ Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, aesKey()); byte[] password = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword.getBytes("UTF-8"))); @@ -579,16 +589,14 @@ public class PolicyDBDao { } try { if (connection.getResponseCode() == 200) { - logger.info("Received response 200 from pap server on notify"); - //notified = true; + logger.info("PolicyDBDao: NotifyOtherThread received response 200 from pap server on notify"); } else { - logger.warn("connection response code not 200, received: "+connection.getResponseCode()); + logger.warn("PolicyDBDao: NotifyOtherThread connection response code not 200, received: "+connection.getResponseCode()); } } catch (Exception e) { logger.warn("Caught Exception on: connection.getResponseCode() ", e); } - connection.disconnect(); } } @@ -700,7 +708,7 @@ public class PolicyDBDao { //no changes should be being made in this function, we still need to close transaction.rollbackTransaction(); } - private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException{ + private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException, PolicyDBException{ GroupEntity groupRecord = null; long groupIdLong = -1; try{ @@ -789,7 +797,7 @@ public class PolicyDBDao { //set default if it should be if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){ try { - papEngine.SetDefaultGroup(localGroup); + papEngine.setDefaultGroup(localGroup); return; } catch (PAPException e) { PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");"); @@ -824,7 +832,7 @@ public class PolicyDBDao { //call command that corresponds to the change that was made } //this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db - private boolean updateGroupPoliciesInFileSystem(OnapPDPGroup pdpGroup,OnapPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException{ + private boolean updateGroupPoliciesInFileSystem(OnapPDPGroup pdpGroup,OnapPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException, PolicyDBException{ if(!(pdpGroup instanceof StdPDPGroup)){ throw new PAPException("group is not a StdPDPGroup"); } @@ -843,9 +851,10 @@ public class PolicyDBDao { if(currentPolicySet.containsKey(pdpPolicyName)){ newPolicySet.add(currentPolicySet.get(pdpPolicyName)); } else{ + logger.info("PolicyDBDao: Adding the new policy to the PDP group after notification: " + pdpPolicyName); InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); group.copyPolicyToFile(pdpPolicyName,policyStream); - ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(policy.getPolicyName())); + ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(pdpPolicyName)); try { policyStream.close(); } catch (IOException e) { @@ -855,6 +864,7 @@ public class PolicyDBDao { } } } + logger.info("PolicyDBDao: Adding updated policies to group after notification."); if(didUpdate){ newPolicySet.addAll(group.getPolicies()); group.setPolicies(newPolicySet); @@ -862,7 +872,66 @@ public class PolicyDBDao { return didUpdate; } - private String removeExtensionAndVersionFromPolicyName(String originalPolicyName){ + + /* + * This method is called during all pushPolicy transactions and makes sure the file system + * group is in sync with the database groupentity + */ + private StdPDPGroup synchronizeGroupPoliciesInFileSystem(StdPDPGroup pdpGroup, GroupEntity groupentity) throws PAPException, PolicyDBException{ + + HashMap currentPolicyMap = new HashMap<>(); + HashSet newPolicyIdSet = new HashSet<>(); + HashSet newPolicySet = new HashSet<>(); + + for(PDPPolicy pdpPolicy : pdpGroup.getPolicies()){ + currentPolicyMap.put(pdpPolicy.getId(), pdpPolicy); + } + + for(PolicyEntity policy : groupentity.getPolicies()){ + String pdpPolicyId = getPdpPolicyName(policy.getPolicyName(), policy.getScope()); + newPolicyIdSet.add(pdpPolicyId); + + if(currentPolicyMap.containsKey(pdpPolicyId)){ + newPolicySet.add(currentPolicyMap.get(pdpPolicyId)); + } else { + + //convert PolicyEntity object to PDPPolicy + String name = pdpPolicyId.replace(".xml", ""); + name = name.substring(0, name.lastIndexOf(".")); + InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); + pdpGroup.copyPolicyToFile(pdpPolicyId,name,policyStream); + URI location = Paths.get(pdpGroup.getDirectory().toAbsolutePath().toString(), pdpPolicyId).toUri(); + StdPDPPolicy newPolicy = null; + try { + newPolicy = new StdPDPPolicy(pdpPolicyId, true, removeExtensionAndVersionFromPolicyName(pdpPolicyId),location); + newPolicySet.add(newPolicy); + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error("PolicyDBDao: Exception occurred while creating the StdPDPPolicy newPolicy object " + e.getMessage()); + } + + } + + } + + for(String id : currentPolicyMap.keySet()) { + if(!newPolicyIdSet.contains(id)){ + try { + Files.delete(Paths.get(currentPolicyMap.get(id).getLocation())); + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error("PolicyDBDao: Exception occurred while attempting to delete the old version of the policy file from the group. " + e.getMessage()); + } + } + } + + logger.info("PolicyDBDao: Adding new policy set to group to keep filesystem and DB in sync"); + pdpGroup.setPolicies(newPolicySet); + + return pdpGroup; + } + + private String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException{ return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0]; } @@ -871,14 +940,14 @@ public class PolicyDBDao { * @param originalPolicyName: a policy file name ex: Config_policy.2.xml * @return An array [0]: The policy name, [1]: the policy version, as a string */ - private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){ + private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException{ String policyName = originalPolicyName; String[] nameAndVersion = new String[2]; try{ policyName = removeFileExtension(policyName); nameAndVersion[0] = policyName.substring(0,policyName.lastIndexOf('.')); if(isNullOrEmpty(nameAndVersion[0])){ - throw new Exception(); + throw new PolicyDBException(); } } catch(Exception e){ nameAndVersion[0] = originalPolicyName; @@ -887,7 +956,7 @@ public class PolicyDBDao { try{ nameAndVersion[1] = policyName.substring(policyName.lastIndexOf('.')+1); if(isNullOrEmpty(nameAndVersion[1])){ - throw new Exception(); + throw new PolicyDBException(); } } catch(Exception e){ nameAndVersion[1] = "1"; @@ -1137,6 +1206,41 @@ public class PolicyDBDao { } } + + public StdPDPGroup auditLocalFileSystem(StdPDPGroup group){ + + logger.info("Starting Local File System group audit"); + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + StdPDPGroup updatedGroup = null; + try { + Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + groupQuery.setParameter("groupId", group.getId()); + groupQuery.setParameter("deleted", false); + List groupQueryList = groupQuery.getResultList(); + if(groupQueryList!=null){ + GroupEntity dbgroup = (GroupEntity)groupQueryList.get(0); + updatedGroup = synchronizeGroupPoliciesInFileSystem(group, dbgroup); + } + } catch (PAPException e) { + logger.error(e); + } catch (PolicyDBException e) { + logger.error(e); + } catch (Exception e) { + logger.error(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group "+group.getId()+" exists"); + } + + em.getTransaction().commit(); + em.close(); + + logger.info("Group was updated during file system audit: " + updatedGroup.toString()); + return updatedGroup; + + } + public void deleteAllGroupTables(){ logger.debug("PolicyDBDao.deleteAllGroupTables() called"); EntityManager em = emf.createEntityManager(); @@ -2149,7 +2253,7 @@ public class PolicyDBDao { String prefix = null; if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) { - prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName())); + prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.lastIndexOf(policy.policyAdapter.getPolicyName())); if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){ String configData = ""; try{ @@ -2584,7 +2688,7 @@ public class PolicyDBDao { @Override - public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) throws PAPException { + public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) throws PolicyDBException { logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called"); if(group == null){ throw new IllegalArgumentException("PDPGroup group cannot be null"); @@ -2595,7 +2699,7 @@ public class PolicyDBDao { if(group.isDefaultGroup()){ PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be."); - throw new PAPException("You cannot delete the default group."); + throw new PolicyDBException("You cannot delete the default group."); } synchronized(emLock){ checkBeforeOperationRun(); @@ -2665,7 +2769,7 @@ public class PolicyDBDao { } } else { PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to"); - throw new PAPException("Group has PDPs. Must provide a group for them to move to"); + throw new PolicyDBException("Group has PDPs. Must provide a group for them to move to"); } } @@ -2681,8 +2785,8 @@ public class PolicyDBDao { } @Override - public void addPolicyToGroup(String groupID, String policyID, String username) { - logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called"); + public StdPDPGroup addPolicyToGroup(String groupID, String policyID, String username) throws PolicyDBException { + logger.info("PolicyDBDao: addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called"); if(isNullOrEmpty(groupID, policyID, username)){ throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty"); } @@ -2706,6 +2810,7 @@ public class PolicyDBDao { PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); } + //we need to convert the form of the policy id that is used groups into the form that is used //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml) String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID); @@ -2728,23 +2833,37 @@ public class PolicyDBDao { PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); } + logger.info("PolicyDBDao: Getting group and policy from database"); GroupEntity group = (GroupEntity)groupQueryList.get(0); PolicyEntity policy = (PolicyEntity)policyQueryList.get(0); Iterator policyIt = group.getPolicies().iterator(); String policyName = getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0]; + + logger.info("PolicyDBDao: policyName retrieved is " + policyName); try{ - while(policyIt.hasNext()){ - PolicyEntity pol = policyIt.next(); - if(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){ - policyIt.remove(); - } - } + while(policyIt.hasNext()){ + PolicyEntity pol = policyIt.next(); + if(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){ + policyIt.remove(); + } + } }catch(Exception e){ - logger.debug(e); + logger.debug(e); PolicyLogger.error("Could not delete old versions for policy "+policy.getPolicyName()+", ID: "+policy.getPolicyId()); } group.addPolicyToGroup(policy); em.flush(); + + // After adding policy to the db group we need to make sure the filesytem group is in sync with the db group + try { + StdPDPGroup pdpGroup = (StdPDPGroup) papEngine.getGroup(group.getGroupId()); + return synchronizeGroupPoliciesInFileSystem(pdpGroup, group); + } catch (PAPException e) { + logger.debug(e); + PolicyLogger.error("PolicyDBDao: Could not synchronize the filesystem group with the database group. " + e.getMessage()); + } + + return null; } } @@ -2802,16 +2921,16 @@ public class PolicyDBDao { String computeScope(String fullPath, String pathToExclude){ return PolicyDBDao.computeScope(fullPath, pathToExclude); } - String encryptPassword(String password) throws Exception{ + String encryptPassword(String password) throws InvalidKeyException, UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{ return PolicyDBDao.encryptPassword(password); } - String decryptPassword(String password) throws Exception{ + String decryptPassword(String password) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{ return PolicyDBDao.decryptPassword(password); } String getDescriptionFromXacml(String xacmlData){ return PolicyDBDao.getDescriptionFromXacml(xacmlData); } - String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){ + String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException{ return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName); } }