com.denimgroup.threadfix.data.dao.hibernate.HibernateVulnerabilitySearchDao.java Source code

Java tutorial

Introduction

Here is the source code for com.denimgroup.threadfix.data.dao.hibernate.HibernateVulnerabilitySearchDao.java

Source

////////////////////////////////////////////////////////////////////////
//
//     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";
    }

}