Package com.denimgroup.threadfix.webapp.controller

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

////////////////////////////////////////////////////////////////////////
//
//     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.*;
import com.denimgroup.threadfix.data.enums.FrameworkType;
import com.denimgroup.threadfix.logging.SanitizedLogger;
import com.denimgroup.threadfix.remote.response.RestResponse;
import com.denimgroup.threadfix.service.*;
import com.denimgroup.threadfix.service.beans.DefectTrackerBean;
import com.denimgroup.threadfix.service.beans.TableSortBean;
import com.denimgroup.threadfix.service.defects.AbstractDefectTracker;
import com.denimgroup.threadfix.service.defects.DefectTrackerFactory;
import com.denimgroup.threadfix.service.defects.ProjectMetadata;
import com.denimgroup.threadfix.service.defects.VersionOneDefectTracker;
import com.denimgroup.threadfix.service.defects.utils.DynamicFormField;
import com.denimgroup.threadfix.service.enterprise.EnterpriseTest;
import com.denimgroup.threadfix.service.util.ControllerUtils;
import com.denimgroup.threadfix.service.util.PermissionUtils;
import com.denimgroup.threadfix.views.AllViews;
import com.denimgroup.threadfix.webapp.validator.BeanValidator;
import com.denimgroup.threadfix.webapp.viewmodels.DefectViewModel;
import com.denimgroup.threadfix.webapp.viewmodels.VulnerabilityCollectionModel;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.SerializationConfig;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.denimgroup.threadfix.CollectionUtils.*;
import static com.denimgroup.threadfix.service.util.ControllerUtils.writeSuccessObjectWithView;

@Controller
@RequestMapping("/organizations/{orgId}/applications")
@SessionAttributes({"defectTracker", "application", "waf", "defectViewModel", "scanParametersBean"})
public class ApplicationsController {

    public ApplicationsController(){}

  private final SanitizedLogger log = new SanitizedLogger(ApplicationsController.class);

    private static final String ERROR_MSG = "error_msg";

    @Autowired
  private FindingService findingService;
    @Autowired
    private GenericVulnerabilityService genericVulnerabilityService;
    @Autowired
  private ApplicationCriticalityService applicationCriticalityService;
    @Autowired
  private ApplicationService applicationService;
    @Autowired
  private DefectTrackerService defectTrackerService;
    @Autowired
  private WafService wafService;
    @Autowired
  private OrganizationService organizationService;
    @Autowired
  private UserService userService;
    @Autowired
  private ChannelVulnerabilityService channelVulnerabilityService;
    @Autowired
    private ChannelTypeService channelTypeService;
    @Autowired
    private ScanService scanService;
    @Autowired
    private TagService tagService;

  @InitBinder
  public void initBinder(WebDataBinder dataBinder) {
    dataBinder.setValidator(new BeanValidator());
  }

  @RequestMapping("/{appId}")
  public String detail(@PathVariable("orgId") Integer orgId, @PathVariable("appId") Integer appId,
      Model model, HttpServletRequest request) {
    if (!PermissionUtils.isAuthorized(Permission.READ_ACCESS, orgId, appId)) {
      return "403";
    }
   
    Application application = applicationService.loadApplication(appId);
    if (application == null || !application.isActive()) {
      log.warn(ResourceNotFoundException.getLogMessage("Application", appId));
      throw new ResourceNotFoundException();
    }

    TableSortBean falsePositiveBean = new TableSortBean();
    falsePositiveBean.setFalsePositive(true);
   
    long numVulns = applicationService.getVulnCount(appId, true);
    long numClosedVulns = applicationService.getVulnCount(appId, false);
    long falsePositiveCount = applicationService.getCount(appId, falsePositiveBean);
   
    TableSortBean hiddenBean = new TableSortBean();
    hiddenBean.setHidden(true);
   
        PermissionUtils.addPermissions(model, orgId, appId, Permission.CAN_MANAGE_APPLICATIONS,
        Permission.CAN_UPLOAD_SCANS,
        Permission.CAN_MODIFY_VULNERABILITIES,
        Permission.CAN_MANAGE_VULN_FILTERS,
        Permission.CAN_SUBMIT_DEFECTS,
//        Permission.CAN_VIEW_JOB_STATUSES,
        Permission.CAN_GENERATE_REPORTS,
        Permission.CAN_MANAGE_DEFECT_TRACKERS,
        Permission.CAN_MANAGE_USERS,
                Permission.CAN_MANAGE_TAGS);
   
    if (application.getPassword() != null && !"".equals(application.getPassword())) {
      application.setPassword(Application.TEMP_PASSWORD);
    }

        model.addAttribute("tagList", application.getTags());
    model.addAttribute("urlManualList", findingService.getAllManualUrls(appId));
    model.addAttribute("numVulns", numVulns);
    model.addAttribute("defectTracker", new DefectTracker());
    model.addAttribute("waf", new Waf());
    model.addAttribute("newWaf", new Waf());
    model.addAttribute(new VulnerabilityCollectionModel());
        model.addAttribute("activeTab", getActiveTab(request, falsePositiveCount, numClosedVulns));
    model.addAttribute(application);
    model.addAttribute("finding", new Finding());
    model.addAttribute(new DefectViewModel());
        model.addAttribute("isEnterprise", EnterpriseTest.isEnterprise());
    if (PermissionUtils.isAuthorized(Permission.CAN_MANAGE_USERS,orgId,appId)) {
      model.addAttribute("users", userService.getPermissibleUsers(orgId, appId));
    }
    model.addAttribute("manualChannelVulnerabilities", channelVulnerabilityService.loadAllManual());
        addAttrForScheduledScanTab(model);
    return "applications/detail";
  }

    private ObjectWriter getWriter() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

        return mapper.writerWithView(AllViews.FormInfo.class);
    }

    @RequestMapping("{appId}/objects")
    public @ResponseBody String getBaseObjects(@PathVariable("appId") Integer appId) throws IOException {
        Map<String, Object> map = new HashMap<>();

        Application application = applicationService.loadApplication(appId);

        applicationService.decryptRepositoryCredentials(application);

        // manual Finding form
        map.put("manualSeverities", findingService.getManualSeverities());
        map.put("recentPathList", findingService.getRecentDynamicPaths(appId));
        map.put("recentFileList", findingService.getRecentStaticPaths(appId));
        map.put("manualChannelVulnerabilities", channelVulnerabilityService.loadAllManual());

        // defect tracker add form
        map.put("defectTrackerList", defectTrackerService.loadAllDefectTrackers());
        map.put("defectTrackerTypeList", defectTrackerService.loadAllDefectTrackerTypes());

        map.put("wafList", wafService.loadAll());
        map.put("wafTypeList", wafService.loadAllWafTypes());

        // basic information
        map.put("application", application);

        // scans tab
        map.put("scans", application.getScans());

        // doc tab
        map.put("documents", application.getDocuments());

        // scan agent tasks tab
        map.put("scanAgentTasks", application.getScanQueueTasks());

        // scheduled scan tab
        map.put("scheduledScans", application.getScheduledScans());

        // edit form
        map.put("applicationTypes", FrameworkType.values());
        map.put("applicationCriticalityList", applicationCriticalityService.loadAll());
        map.put("teams", organizationService.loadAllActive());

        // tagging
        map.put("tags", tagService.loadAll());

        map.put("applicationTags", application.getTags());

        return getSerializedMap(map);
    }

    private String getSerializedMap(Map<String, Object> map) throws IOException {
        return getWriter().writeValueAsString(RestResponse.success(map));
    }

    private String getActiveTab(HttpServletRequest request, long falsePositiveCount, long numClosedVulns) {
        String activeTab = ControllerUtils.getActiveTab(request);
        if (activeTab != null) {
            if (activeTab.equals(ControllerUtils.FALSE_POSITIVE_TAB) && falsePositiveCount == 0)
                return null;
            if (activeTab.equals(ControllerUtils.CLOSED_VULN_TAB) && numClosedVulns == 0)
                return null;
        }

        return activeTab;
    }

    private void addAttrForScheduledScanTab(Model model) {
        List<String> scannerTypeList = list();
        List<ChannelType> channelTypeList = channelTypeService.getChannelTypeOptions(null);
        for (ChannelType type: channelTypeList) {
            scannerTypeList.add(type.getName());
        }

        Collections.sort(scannerTypeList);
        model.addAttribute("scannerTypeList", scannerTypeList);
        model.addAttribute("scheduledScan", new ScheduledScan());
        model.addAttribute("frequencyTypes", ScheduledFrequencyType.values());
        model.addAttribute("periodTypes", ScheduledPeriodType.values());
        model.addAttribute("scheduledDays", DayInWeek.values());
    }

    private void addAdditionalScannerInfoField(@Nonnull List<DynamicFormField> formFields){
        DynamicFormField additionalScannerInfoField = new DynamicFormField();
        additionalScannerInfoField.setName("AdditionalScannerInfo");
        additionalScannerInfoField.setLabel("Additional Scanner Info");
        additionalScannerInfoField.setRequired(false);
        additionalScannerInfoField.setType("checkbox");
        additionalScannerInfoField.setActive(true);
        additionalScannerInfoField.setEditable(true);
        additionalScannerInfoField.setSupportsMultivalue(false);

        formFields.add(additionalScannerInfoField);
    }
 
  // TODO move this to a different spot so as to be less annoying
  private Map<String, Object> addDefectModelAttributes(int appId, int orgId, boolean addDefectIds) {
    if (!PermissionUtils.isAuthorized(Permission.CAN_SUBMIT_DEFECTS, orgId, appId)) {
      return null;
    }
   
    Application application = applicationService.loadApplication(appId);
    if (application == null || !application.isActive()) {
      log.warn(ResourceNotFoundException.getLogMessage("Application", appId));
      throw new ResourceNotFoundException();
    }
   
    if (application.getDefectTracker() == null ||
        application.getDefectTracker().getDefectTrackerType() == null) {
      return null;
    }

    applicationService.decryptCredentials(application);

    AbstractDefectTracker dt = DefectTrackerFactory.getTracker(application);
    ProjectMetadata data = null;

        List<Defect> defectList = null;
        Map<String, Object> map = new HashMap<>();
    if (dt != null) {
            if (addDefectIds) {
                defectList = dt.getDefectList();
                if (dt.getLastError() != null && !dt.getLastError().isEmpty()) {
                    map.put(ERROR_MSG, dt.getLastError());
                    return map;
                }
            } else {
                defectList = list();
            }

      data = dt.getProjectMetadata();
            if (dt.getLastError() != null && !dt.getLastError().isEmpty()) {
                map.put(ERROR_MSG, dt.getLastError());
                return map;
            }

            // adding additional scanner info checkbox, checking for null dynamicformfields
            List<DynamicFormField> editableFields = data.getEditableFields();

            if (editableFields != null) {
                addAdditionalScannerInfoField(editableFields);

                //remove Order field in Version One dynamic form
                if (dt.getClass().equals(VersionOneDefectTracker.class)) {
                    DynamicFormField orderField = null;
                    for (DynamicFormField field : editableFields) {
                        if (field.getName().equals("Order")) {
                            orderField = field;
                        }
                    }

                    if (orderField != null) {
                        editableFields.remove(orderField);
                    }
                }
            }
    }

    map.put("defectTrackerName", application.getDefectTracker().getDefectTrackerType().getName());
    map.put("defectList", defectList);
    map.put("projectMetadata", data);

    return map;
  }

  @RequestMapping("/{appId}/defectSubmission")
  public @ResponseBody RestResponse<Map<String, Object>> getDefectSubmissionForm(
            @PathVariable("orgId") int orgId,
      @PathVariable("appId") int appId) {

    Map<String, Object> returnMap = addDefectModelAttributes(appId, orgId, false);

        if (returnMap.get(ERROR_MSG) != null) {
            return RestResponse.failure(returnMap.get(ERROR_MSG).toString());
        } else {
            return RestResponse.success(returnMap);
        }
  }

  @RequestMapping("/{appId}/defectSubmissionWithIssues")
  public @ResponseBody RestResponse<Map<String, Object>> getDefectSubmissionWithIssues(
            @PathVariable("orgId") int orgId,
      @PathVariable("appId") int appId) {

    Map<String, Object> returnMap = addDefectModelAttributes(appId, orgId, true);

        if (returnMap.get(ERROR_MSG) != null) {
            return RestResponse.failure(returnMap.get(ERROR_MSG).toString());
        } else {
            return RestResponse.success(returnMap);
        }
  }
 
  @PreAuthorize("hasRole('ROLE_CAN_MANAGE_APPLICATIONS')")
  @RequestMapping("/{appId}/delete")
  public String processLinkDelete(@PathVariable("orgId") int orgId,
      @PathVariable("appId") int appId, SessionStatus status) {
   
    if (!PermissionUtils.isAuthorized(Permission.READ_ACCESS, orgId, appId)) {
      return "403";
    }
   
    Application application = applicationService.loadApplication(appId);
    if (application != null && application.isActive()) {
      applicationService.deactivateApplication(application);
      status.setComplete();
    } else {
      log.warn(ResourceNotFoundException.getLogMessage("Application", appId));
      throw new ResourceNotFoundException();
    }
   
    return "redirect:/organizations/" + String.valueOf(orgId);
  }

  // TODO move this elsewhere?
  @RequestMapping(value = "/jsontest", method = RequestMethod.POST)
  public @ResponseBody RestResponse<?> readJson(@ModelAttribute DefectTrackerBean bean) {
    DefectTracker defectTracker = defectTrackerService.loadDefectTracker(bean
        .getDefectTrackerId());
    AbstractDefectTracker dt = DefectTrackerFactory.getTrackerByType(defectTracker,
        bean.getUserName(), bean.getPassword());
    if (dt == null) {
      log.warn("Incorrect Defect Tracker credentials submitted.");
      return RestResponse.failure("Authentication failed.");
    }
    List<String> result = dt.getProductNames();
    if (result.isEmpty() || (result.size() == 1 && result.contains("Authentication failed"))) {
      return RestResponse.failure(JSONObject.quote(dt.getLastError()));
    }

        // ensure there are no duplicates. There's probably a better idiom
        result = listFrom(setFrom(result));

        Collections.sort(result);

    return RestResponse.success(result);
  }
 
  @RequestMapping("/{appId}/getDefectsFromDefectTracker")
  public String getDefectsFromDefectTracker(@PathVariable("appId") int appId, Model model) {
   
    log.info("Start getting defect list.");
    Application application = applicationService.loadApplication(appId);
    if (application == null || !application.isActive()) {
      log.warn(ResourceNotFoundException.getLogMessage("Application", appId));
      throw new ResourceNotFoundException();
    }
   
    if (application.getDefectTracker() == null ||
        application.getDefectTracker().getDefectTrackerType() == null) {
      return "";
    }
    applicationService.decryptCredentials(application);

    AbstractDefectTracker dt = DefectTrackerFactory.getTracker(application);
    List<Defect> defectList = list();
   
    ProjectMetadata data = null;
    if (dt != null) {
      data = dt.getProjectMetadata();
      defectList = dt.getDefectList();
    }
    model.addAttribute("projectMetadata", data);
    model.addAttribute("defectList", defectList);
    model.addAttribute(new DefectViewModel());
    model.addAttribute("contentPage", "defects/mergeDefectForm.jsp");
   
    log.info("Ended getting defect list.");
   
    return "ajaxSuccessHarness";
  }

    @RequestMapping(value = "/{appId}/unmappedTable", method = RequestMethod.POST)
    public @ResponseBody String unmappedScanTable(@ModelAttribute TableSortBean bean,
                                                  @PathVariable("appId") Integer appId,
                                                  @PathVariable("orgId") Integer orgId) throws IOException {

        if (!PermissionUtils.isAuthorized(Permission.READ_ACCESS,orgId,appId)) {
            return "403";
        }

        long numFindings = applicationService.getUnmappedFindingCount(appId);
        long numPages = numFindings / 100;

        if (numFindings % 100 == 0) {
            numPages -= 1;
        }

        if (bean.getPage() >= numPages) {
            bean.setPage((int) (numPages + 1));
        }

        if (bean.getPage() < 1) {
            bean.setPage(1);
        }

        bean.setApplicationId(appId);

        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("numPages", numPages);
        responseMap.put("page", bean.getPage());
        responseMap.put("numFindings", numFindings);
        responseMap.put("findingList", findingService.getUnmappedFindingTable(bean));

        return writeSuccessObjectWithView(responseMap, AllViews.TableRow.class);
    }

    @RequestMapping(value = "/{appId}/cwe", method = RequestMethod.GET)
    public @ResponseBody Object getGenericVulnerabilities() throws IOException {
        return writeSuccessObjectWithView(
                genericVulnerabilityService.loadAll(),
                AllViews.TableRow.class);
    }
}
TOP

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

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.