Package com.denimgroup.threadfix.webapp.controller

Source Code of com.denimgroup.threadfix.webapp.controller.PortfolioReportController

////////////////////////////////////////////////////////////////////////
//
//     Copyright (c) 2009-2014 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.webapp.controller;

import com.denimgroup.threadfix.data.entities.Application;
import com.denimgroup.threadfix.data.entities.ApplicationCriticality;
import com.denimgroup.threadfix.data.entities.Organization;
import com.denimgroup.threadfix.logging.SanitizedLogger;
import com.denimgroup.threadfix.service.OrganizationService;
import com.denimgroup.threadfix.service.util.ControllerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.denimgroup.threadfix.CollectionUtils.list;

// TODO split into a service? This is all in the controller layer.
@Controller
@RequestMapping("/reports/portfolio")
public class PortfolioReportController {
 
  private final SanitizedLogger log = new SanitizedLogger(PortfolioReportController.class);

  private OrganizationService organizationService; 

  @Autowired
  public PortfolioReportController(OrganizationService organizationService) {
    this.organizationService = organizationService;
  }

  /**
   * This report is generated by storing the date / criticality information in a 2D integer matrix
   * and then transforming it into a 2D String matrix with percentages in the controller,
   * then feeding that into a simple JSP for the view.
   *
   * @param model
   * @param request
   * @return
   */
  @RequestMapping(method = RequestMethod.GET)
  public String index(Model model, HttpServletRequest request, int teamId) {
   
    Organization org = null;
    String teamName = null;
   
    if (teamId != 0) {
      org = organizationService.loadById(teamId);
      if (org != null && org.getName() != null) {
        teamName = org.getName();
      }
    }
   
    if (teamName == null) {
      teamName = "All";
    }
   
    Calendar now = Calendar.getInstance();
    List<Organization> teams;
   
    if (org == null) {
      teams = organizationService.loadAllActive();
    } else {
      teams = list();
      teams.add(org);
    }
   
    int[][] appsByCriticality = new int[][] {{0, 0, 0, 0, 0, 0, 0, 0, 0},
                     {0, 0, 0, 0, 0, 0, 0, 0, 0},
                     {0, 0, 0, 0, 0, 0, 0, 0, 0},
                     {0, 0, 0, 0, 0, 0, 0, 0, 0}};
   
    if (teams == null || teams.isEmpty()) {
      log.warn("No Teams. Redirecting to main page.");
      return "redirect:/";
    }
    log.info("Generating the portfolio-level report.");
   
    Integer numberApplications = 0, numberScans = 0, numberApplicationsNeverScanned = 0;

    // Generate the big table
    List<List<String>> tableContents = list();
    List<String> blankRow = null;
   
    List<Boolean> oldArray = list();
   
    // each time through generate a team row for the Team and
    for (Organization team : teams) {
      if (team == null || !team.isActive()) {
        continue;
      }     
     
      List<String> teamRow = null;
      List<List<String>> appRows = list();
     
      if (team.getActiveApplications() == null || team.getApplications().isEmpty()) {
        teamRow = Arrays.asList("Team: " + team.getName(), "0", "Never");
        oldArray.add(true);
      } else {
        Integer totalScans = 0, lowerBound = null, upperBound = 0;
       
        int startCount = oldArray.size();
        oldArray.add(false);
       
        for (Application app : team.getApplications()) {
          if (app == null || !app.isActive())
            continue;
         
          updateCriticalityCounts(appsByCriticality, app, now);
          numberApplications += 1;
         
          String criticality = "";
          if (app.getApplicationCriticality() != null &&
              app.getApplicationCriticality().getName() != null) {
            criticality = app.getApplicationCriticality().getName();
          }
         
          if (app.getScans() == null || app.getScans().isEmpty()) {
            numberApplicationsNeverScanned += 1;
            appRows.add(Arrays.asList(app.getName(), criticality, "0", "Never"));
            oldArray.add(false);
          } else {
            totalScans += app.getScans().size();
            numberScans += app.getScans().size();
            Integer daysSinceLatestScan = getAgeInDays(now, app.getScans().get(0).getImportTime());
            if (lowerBound == null || daysSinceLatestScan < lowerBound) {
              lowerBound = daysSinceLatestScan;
            }
            if (upperBound == null || daysSinceLatestScan > upperBound) {
              upperBound = daysSinceLatestScan;
            }
            appRows.add(Arrays.asList(
                app.getName(),
                criticality,
                String.valueOf(app.getScans().size()),
                daysSinceLatestScan.toString()
              ));
            oldArray.add(daysSinceLatestScan > 365);
          }
        }
       
        if (totalScans == 0 || lowerBound == null || upperBound == null) {
          teamRow = Arrays.asList("Team: " + team.getName(),"", "0", "Never" );
        } else {
          if (lowerBound.equals(upperBound)) {
            teamRow = Arrays.asList("Team: " + team.getName(),"", totalScans.toString(),
                lowerBound.toString());
          } else {
            teamRow = Arrays.asList("Team: " + team.getName(),"", totalScans.toString(),
                lowerBound.toString() + "-" + upperBound.toString());
          }
        }
       
        if (upperBound != null) {
          oldArray.set(startCount, upperBound > 365);
        } else {
          oldArray.set(startCount, false);
        }
      }
     
      tableContents.add(teamRow);
      tableContents.addAll(appRows);
      tableContents.add(blankRow);
      oldArray.add(false);
    }
   
    if (tableContents.size() == 0) {
      log.warn("No Active Teams. Redirecting to main page.");
      ControllerUtils.addErrorMessage(request, "No active Teams found.");
      return "redirect:/reports";
    }
   
    tableContents.remove(tableContents.size() - 1);
   
    model.addAttribute("totalApps", numberApplications);
    model.addAttribute("totalScans", numberScans);
    model.addAttribute("numberApplicationsNeverScanned", numberApplicationsNeverScanned);
    model.addAttribute("appsByCriticality", createDateTable(appsByCriticality));
    model.addAttribute("tableContents", tableContents);
    model.addAttribute("old",oldArray);
    model.addAttribute("teamName", teamName);
    model.addAttribute("contentPage", "reports/portfolioReport.jsp");
    return "ajaxSuccessHarness";
  }
 
  private String[][] createDateTable(int[][] appsByCriticality) {
    String[] titles = { "Low", "Medium", "High", "Critical"};
    String[][] returnArray = new String[5][10];
    int[] totals = {0,0,0,0,0,0,0,0,0};
   
    for (int i = 0; i < 4; i++) {
      returnArray[i][0] = titles[3-i];
     
      int total = appsByCriticality[3-i][8];
      for (int j = 0; j < 8; j++ ) {
        if (appsByCriticality[3-i][j] != 0) {
          returnArray[i][j+1] = String.valueOf(appsByCriticality[3-i][j]) +
                        " (" +
                        String.valueOf(100*appsByCriticality[3-i][j]/total) +
                        "%)";
          totals[j] += appsByCriticality[3-i][j];
        } else {
          returnArray[i][j+1] = "0";
        }
      }
      returnArray[i][9] = String.valueOf(total);
      totals[8] += total;
     
    }
   
    returnArray[4][0] = "Total";
   
    for (int i = 0; i < 8; i++) {
      if (totals[i] != 0) {
        returnArray[4][i+1] = String.valueOf(totals[i]) +
                      " (" +
                      String.valueOf(100*totals[i]/totals[8]) +
                      "%)";
      } else {
        returnArray[4][i+1] = "0";
      }
    }
   
    returnArray[4][9] = String.valueOf(totals[8]);
   
    return returnArray;
  }
 
  /**
   * Update the app counts by criticality so that we can use those stats in the report.
   * @param app
   */
  private void updateCriticalityCounts(int[][] appsByCriticality, Application app, Calendar now) {

    if (app != null && app.getApplicationCriticality() != null &&
        app.getApplicationCriticality().getName() != null) {
     
      int arrayIndex = ApplicationCriticality.NUMERIC_MAP.get(
          app.getApplicationCriticality().getName());
     
      appsByCriticality[arrayIndex][8] += 1;

      if (app.getScans() == null || app.getScans().isEmpty()) {
        appsByCriticality[arrayIndex][7] += 1;
      } else {
        int numMonths = getAgeInMonths(now, app.getScans().get(0).getImportTime());
        if (numMonths == 0) {
          appsByCriticality[arrayIndex][0] += 1;
        } else {
          int index = 0;

          if (numMonths < 4) {
            index = numMonths-1;
          } else if (numMonths < 7) {
            index = 3;
          } else if (numMonths < 10) {
            index = 4;
          } else if (numMonths < 13) {
            index = 5;
          } else {
            index = 6;
          }
         
          appsByCriticality[arrayIndex][index] += 1;
        }
      }
    }
  }
 
  /**
   * @param now
   * @param older
   * @return number of days difference between the older calendar and the newer one.
   */
  private int getAgeInDays(Calendar now, Calendar older) {
    int numDays = 0;
   
    Date temp = older.getTime();
   
    while (older.before(now)) {
      numDays += 1;
      older.add(Calendar.DATE, 1);
    }
   
    older.setTime(temp);
   
    return numDays;
  }
 
  /**
   * @param now
   * @param older
   * @return number of days difference between the older calendar and the newer one.
   */
  private int getAgeInMonths(Calendar now, Calendar older) {
    int numMonths = 0;
   
    Date temp = older.getTime();
   
    while (older.before(now)) {
      numMonths += 1;
      older.add(Calendar.MONTH, 1);
    }
   
    older.setTime(temp);
   
    return numMonths;
  }
 
}
TOP

Related Classes of com.denimgroup.threadfix.webapp.controller.PortfolioReportController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.