Java tutorial
//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2009-2015 Denim Group, Ltd. // // The contents of this file are subject to the Mozilla Public License // Version 2.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is ThreadFix. // // The Initial Developer of the Original Code is Denim Group, Ltd. // Portions created by Denim Group, Ltd. are Copyright (C) // Denim Group, Ltd. All Rights Reserved. // // Contributor(s): Denim Group, Ltd. // //////////////////////////////////////////////////////////////////////// package com.denimgroup.threadfix.data.dao.hibernate; import com.denimgroup.threadfix.data.dao.VulnerabilitySearchDao; import com.denimgroup.threadfix.data.entities.Vulnerability; import com.denimgroup.threadfix.data.entities.VulnerabilitySearchParameters; import com.denimgroup.threadfix.data.entities.VulnerabilityTreeElement; import org.hibernate.Criteria; import org.hibernate.SessionFactory; import org.hibernate.classic.Session; import org.hibernate.criterion.Order; import org.hibernate.criterion.ProjectionList; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.transform.Transformers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; import java.util.Map; import static com.denimgroup.threadfix.CollectionUtils.list; /** * Created by mac on 5/7/14. */ @Repository @SuppressWarnings("unchecked") public class HibernateVulnerabilitySearchDao implements VulnerabilitySearchDao { @Autowired private SessionFactory sessionFactory; private Criteria performLookupSetup(VulnerabilitySearchParameters parameters) { assert parameters != null; Criteria criteria = VulnerabilitySearchCriteriaConstructor .getCriteriaWithRestrictions(sessionFactory.getCurrentSession(), parameters); if (parameters.getNumberVulnerabilities() != null) { criteria.setMaxResults(parameters.getNumberVulnerabilities()); if (parameters.getPage() != null) criteria.setFirstResult(parameters.getNumberVulnerabilities() * (parameters.getPage() - 1)); } return criteria; } private void addOrders(VulnerabilitySearchParameters parameters, Criteria criteria) { for (String desc : parameters.getDescList()) { criteria.addOrder(Order.desc(desc)); } if (parameters.getAscList() == null || parameters.getAscList().size() == 0) criteria.addOrder(Order.asc("surface.path")); else for (String asc : parameters.getAscList()) { criteria.addOrder(Order.asc(asc)); } } @Override public List<Vulnerability> performLookup(VulnerabilitySearchParameters parameters) { assert parameters != null; Criteria criteria = performLookupSetup(parameters); // this is in this method and not the setup because it doesn't play nice with count addOrders(parameters, criteria); return (List<Vulnerability>) criteria.list(); } @Override public long performLookupCount(VulnerabilitySearchParameters parameters) { assert parameters != null; Criteria criteria = performLookupSetup(parameters); Number numVulns = (Number) criteria.setProjection(Projections.rowCount()).uniqueResult(); return numVulns.longValue(); } @Override public List<VulnerabilityTreeElement> getTree(VulnerabilitySearchParameters parameters) { assert parameters != null; Criteria criteria = VulnerabilitySearchCriteriaConstructor .getCriteriaWithRestrictions(sessionFactory.getCurrentSession(), parameters); criteria.setProjection(Projections.projectionList().add(Projections.countDistinct("id"), "numResults") .add(Projections.groupProperty("severity.intValue")) .add(Projections.groupProperty("genericVulnAlias.id"), "genericVulnerabilityId") .add(Projections.groupProperty("genericVulnAlias.name"), "genericVulnerabilityName") .add(Projections.groupProperty("genericVulnAlias.cweId"), "genericVulnerabilityDisplayId") .add(Projections.groupProperty("severity.intValue"), "severityIntValue")) .addOrder(Order.desc("severityIntValue")).addOrder(Order.desc("numResults")); criteria.setResultTransformer(Transformers.aliasToBean(VulnerabilityTreeElement.class)); return (List<VulnerabilityTreeElement>) criteria.list(); } @Override public List<Object> getAges(VulnerabilitySearchParameters parameters) { assert parameters != null; List<Integer> idList = getVulnIdList(parameters); if (idList.isEmpty()) return list(); List<Object> fullList = list(); // TODO refactor this to reduce duplication or remove the need for it int current = 0; while (current < idList.size()) { int start = current, end = current + 500; if (end > idList.size()) { end = idList.size(); } List<Integer> thisPage = idList.subList(start, end); List<Object> result = sessionFactory.getCurrentSession().createQuery("select new map( " + "avg(" + getDateDiffSql(":current_timestamp", "vuln.openTime") + ") as datediff, " + "vuln.genericSeverity.intValue as severity, vuln.genericSeverity.customName as severityCustomName, " + "vuln.genericSeverity.name as severityName )" + " from Vulnerability vuln where vuln.id in (:idList) " + "group by vuln.genericSeverity.intValue, vuln.genericSeverity.customName, vuln.genericSeverity.name") .setDate("current_timestamp", new Date()).setParameterList("idList", thisPage).list(); fullList.addAll(result); current += 500; } return fullList; } @Override public List<Map> getProgressByType(VulnerabilitySearchParameters parameters) { assert parameters != null; List<Integer> idList = getVulnIdList(parameters); if (idList.isEmpty()) return list(); List<Map> fullList = list(); // TODO refactor this to reduce duplication or remove the need for it int current = 0; while (current < idList.size()) { int start = current, end = current + 500; if (end > idList.size()) { end = idList.size(); } List<Integer> thisPage = idList.subList(start, end); List<Map> result = (List<Map>) sessionFactory.getCurrentSession().createQuery("select new map( " + "avg(" + getDateDiffSql(":current_timestamp", "vuln.openTime") + ") as averageAgeOpen, " + "avg(case when vuln.closeTime is null then (" + getDateDiffSql(":current_timestamp", "vuln.openTime") + ") " + "when vuln.closeTime is not null then (" + getDateDiffSql("vuln.closeTime", "vuln.openTime") + ") end) as averageTimeToClose, " + "vuln.genericVulnerability.name as description, " + "vuln.genericVulnerability.id as vulnId, " + "vuln.genericVulnerability.cweId as cweId, " + "vuln.active as status, " + "count(vuln.id) as total " + ")" + " from Vulnerability vuln where vuln.id in (:idList) " + "group by vuln.genericVulnerability.name, vuln.genericVulnerability.id, vuln.genericVulnerability.cweId, vuln.active") .setDate("current_timestamp", new Date()).setParameterList("idList", thisPage).list(); fullList.addAll(result); current += 500; } return fullList; } @Override public List<Map> getScanComparison(VulnerabilitySearchParameters parameters, boolean isFalsePositive) { assert parameters != null; List<Integer> idList = getVulnIdList(parameters); if (idList.isEmpty()) return list(); Session session = sessionFactory.getCurrentSession(); List<Map> fullList = list(); // TODO refactor this to reduce duplication or remove the need for it int current = 0; while (current < idList.size()) { int start = current, end = current + 500; if (end > idList.size()) { end = idList.size(); } List<Integer> thisPage = idList.subList(start, end); Criteria criteria = session.createCriteria(Vulnerability.class); criteria.createAlias("findings", "finding"); criteria.createAlias("finding.scan", "scan"); criteria.createAlias("scan.applicationChannel", "applicationChannel"); criteria.createAlias("applicationChannel.channelType", "channelType"); criteria.add(Restrictions.in("id", thisPage)); ProjectionList projectionList = Projections.projectionList() .add(Projections.groupProperty("channelType.name"), "channelName") .add(Projections.alias(Projections.countDistinct("id"), "foundCount")); if (!isFalsePositive) { projectionList.add(Projections.groupProperty("foundHAMEndpoint"), "foundHAMEndpoint"); } criteria.setProjection(projectionList); criteria.addOrder(Order.desc("foundCount")); criteria.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); List results = (List<Map>) criteria.list(); fullList.addAll(results); current += 500; } return fullList; } private List<Integer> getVulnIdList(VulnerabilitySearchParameters parameters) { Criteria criteria = VulnerabilitySearchCriteriaConstructor .getCriteriaWithRestrictions(sessionFactory.getCurrentSession(), parameters); criteria.setProjection(Projections.projectionList().add(Projections.property("id"))); List<Integer> idList = (List<Integer>) criteria.list(); return idList; } @Override public Long getCount(VulnerabilitySearchParameters parameters) { return (Long) VulnerabilitySearchCriteriaConstructor .getCriteriaWithRestrictions(sessionFactory.getCurrentSession(), parameters) .setProjection(Projections.rowCount()).uniqueResult(); } private String getDateDiffSql(String toDate, String fromDate) { return "(day(" + toDate + ") + " + getDaysOfMonth(toDate) + " + year(" + toDate + ") * 365) -( day(" + fromDate + ") + " + getDaysOfMonth(fromDate) + " + year( " + fromDate + ") * 365)"; } private String getDaysOfMonth(String date) { return "case when month(" + date + ") = 1 then 0 " + "when month(" + date + ") = 2 then 31 " + "when month(" + date + ") = 3 then 59 " + "when month(" + date + ") = 4 then 90 " + "when month(" + date + ") = 5 then 120 " + "when month(" + date + ") = 6 then 151 " + "when month(" + date + ") = 7 then 181 " + "when month(" + date + ") = 8 then 212 " + "when month(" + date + ") = 9 then 243 " + "when month(" + date + ") = 10 then 273 " + "when month(" + date + ") = 11 then 304 " + "when month(" + date + ") = 12 then 334 end"; } }