Package com.denimgroup.threadfix.service

Source Code of com.denimgroup.threadfix.service.RemoteProviderTypeServiceImpl

////////////////////////////////////////////////////////////////////////
//
//     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.service;

import com.denimgroup.threadfix.data.dao.RemoteProviderTypeDao;
import com.denimgroup.threadfix.data.entities.RemoteProviderApplication;
import com.denimgroup.threadfix.data.entities.RemoteProviderType;
import com.denimgroup.threadfix.data.entities.Scan;
import com.denimgroup.threadfix.importer.interop.RemoteProviderFactory;
import com.denimgroup.threadfix.logging.SanitizedLogger;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.errors.EncryptionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional(readOnly = false)
public class RemoteProviderTypeServiceImpl implements RemoteProviderTypeService {
 
  private final SanitizedLogger log = new SanitizedLogger(RemoteProviderTypeServiceImpl.class);

    @Autowired
  private RemoteProviderTypeDao remoteProviderTypeDao;

    @Autowired
  private RemoteProviderApplicationService remoteProviderApplicationService;

    @Autowired
  private ScanMergeService scanMergeService;

    @Autowired
    private RemoteProviderFactory remoteProviderFactory;

    @Autowired
    private VulnerabilityService vulnerabilityService;

    @Autowired
    RemoteProviderTypeServiceImpl (RemoteProviderTypeDao remoteProviderTypeDao) {
        this.remoteProviderTypeDao = remoteProviderTypeDao;
    }

  @Override
  @Transactional
  public ResponseCode importScansForApplications(Integer remoteProviderTypeId) {
   
    RemoteProviderType type = load(remoteProviderTypeId);
   
    if (type == null) {
      log.error("Type was null, Remote Provider import failed.");
      return ResponseCode.BAD_ID;
    } else {
     
      decryptCredentials(type);
     
      List<RemoteProviderApplication> applications = type.getRemoteProviderApplications();
     
      if (applications == null || applications.isEmpty()) {
        log.error("No applications found, Remote Provider import failed.");
        return ResponseCode.NO_APPS;
      } else {
       
        log.info("Starting scan import for " + applications.size() + " applications.");
       
        for (RemoteProviderApplication application : applications) {
          if (application != null && application.getApplicationChannel() != null) {
            ResponseCode success = importScansForApplication(application);
           
            if (!success.equals(ResponseCode.SUCCESS)) {
              log.info("No scans were imported for Remote Provider application " + application.getNativeName());
            } else {
              log.info("Remote Provider import was successful for application " + application.getNativeName());
            }
          }
        }
       
        return ResponseCode.SUCCESS;
      }
    }
   
  }
 
  @Transactional(readOnly=false)
  @Override
  public ResponseCode updateAll() {
    log.info("Importing scans for all Remote Provider Applications.");
    List<RemoteProviderApplication> apps = remoteProviderApplicationService.loadAllWithMappings();
   
    if (apps == null || apps.size() == 0) {
      log.info("No apps with mappings found. Exiting.");
      return ResponseCode.NO_APPS;
    }
   
    for (RemoteProviderApplication remoteProviderApplication : apps) {
      if (remoteProviderApplication == null || remoteProviderApplication.getRemoteProviderType() == null) {
        continue;
      }
      decryptCredentials(remoteProviderApplication.getRemoteProviderType());
      importScansForApplication(remoteProviderApplication);
    }
   
    log.info("Completed requests for scan imports.");
   
    return ResponseCode.SUCCESS;
  }
 
  @Override
  public ResponseCode importScansForApplication(RemoteProviderApplication remoteProviderApplication) {
   
    if (remoteProviderApplication == null) {
      return ResponseCode.ERROR_OTHER;
    }
   
    List<Scan> resultScans = remoteProviderFactory.fetchScans(remoteProviderApplication);
   
    ResponseCode success = ResponseCode.ERROR_NO_SCANS_FOUND;
    if (resultScans != null && resultScans.size() > 0) {
      Collections.sort(resultScans, new Comparator<Scan>() {
        @Override
        public int compare(Scan scan1, Scan scan2){
          Calendar scan1Time = scan1.getImportTime();
          Calendar scan2Time = scan2.getImportTime();
         
          if (scan1Time == null || scan2Time == null) {
            return 0;
          }
         
          return scan1Time.compareTo(scan2Time);
        }
      });
     
      int noOfScanNotFound = 0;
      int noOfNoNewScans = 0;
      for (Scan resultScan : resultScans) {
        if (resultScan == null || resultScan.getFindings() == null
            || resultScan.getFindings().size() == 0) {
          log.warn("Remote Scan import returned a null scan or a scan with no findings.");
          noOfScanNotFound++;
         
        } else if (remoteProviderApplication.getLastImportTime() != null &&
              (resultScan.getImportTime() == null ||
              !remoteProviderApplication.getLastImportTime().before(
                  resultScan.getImportTime()))) {
          log.warn("Remote Scan was not newer than the last imported scan " +
              "for this RemoteProviderApplication.");
          noOfNoNewScans++;

        } else {
          log.info("Scan was parsed and has findings, passing to ScanMergeService.");
         
          remoteProviderApplication.setLastImportTime(resultScan.getImportTime());
         
          remoteProviderApplicationService.store(remoteProviderApplication);
         
          if (resultScan.getApplicationChannel() == null) {
            if (remoteProviderApplication.getApplicationChannel() != null) {
              resultScan.setApplicationChannel(remoteProviderApplication.getApplicationChannel());
            } else {
              log.error("Didn't have enough application channel information.");
            }
          }
         
          if (resultScan.getApplicationChannel() != null) {
            if (resultScan.getApplicationChannel().getScanList() == null) {
              resultScan.getApplicationChannel().setScanList(new ArrayList<Scan>());
            }
           
            if (!resultScan.getApplicationChannel().getScanList().contains(resultScan)) {
              resultScan.getApplicationChannel().getScanList().add(resultScan);
            }
         
            scanMergeService.processRemoteScan(resultScan);
            success = ResponseCode.SUCCESS;

                        vulnerabilityService.updateVulnerabilityReport(remoteProviderApplication.getApplication());
          }
        }
      }
     
      if (!success.equals(ResponseCode.SUCCESS)) {
        if (noOfNoNewScans > 0) {
          success = ResponseCode.ERROR_NO_NEW_SCANS;
        } else if (noOfScanNotFound > 0) {
          success = ResponseCode.ERROR_NO_SCANS_FOUND;
        }
      }
    }

    return success;
  }

  @Override
  public List<RemoteProviderType> loadAll() {
    List<RemoteProviderType> remoteProviderList = remoteProviderTypeDao.retrieveAll();
   
    if (remoteProviderList != null && remoteProviderList.size() > 0) {
      for (RemoteProviderType type : remoteProviderList) {
        decryptCredentials(type);
      }
    }
   
    return remoteProviderList;
  }

  @Override
  public RemoteProviderType load(String name) {
    return decryptCredentials(remoteProviderTypeDao.retrieveByName(name));
  }

  @Override
  public RemoteProviderType load(int id) {
    return decryptCredentials(remoteProviderTypeDao.retrieveById(id));
  }
 
  /**
   * Put the unencrypted credentials back into the object.
   * @param type
   * @return
   */
  private RemoteProviderType encryptCredentials(RemoteProviderType type) {
    try {
      if (type != null && type.getHasApiKey() && type.getApiKey() != null) {
        type.setEncryptedApiKey(ESAPI.encryptor().encrypt(type.getApiKey()));
      } else if (type != null && type.getHasUserNamePassword() &&
          type.getUsername() != null && type.getPassword() != null) {
        type.setEncryptedUsername(ESAPI.encryptor().encrypt(type.getUsername()));
        type.setEncryptedPassword(ESAPI.encryptor().encrypt(type.getPassword()));
      }
    } catch (EncryptionException e) {
      log.warn("Encountered an ESAPI encryption exception. Check your ESAPI configuration.", e);
    }
   
    return type;
  }
 
  /**
   * Move the unencrypted credentials in the transient fields into the
   * encrypted fields that will be saved.
   * @param type
   * @return
   */
  @Override
  public RemoteProviderType decryptCredentials(RemoteProviderType type) {
    try {
      if (type != null && type.getHasApiKey() && type.getEncryptedApiKey() != null) {
        type.setApiKey(ESAPI.encryptor().decrypt(type.getEncryptedApiKey()));
      } else if (type != null && type.getHasUserNamePassword() &&
          type.getEncryptedUsername() != null && type.getEncryptedPassword() != null) {
        type.setUsername(ESAPI.encryptor().decrypt(type.getEncryptedUsername()));
        type.setPassword(ESAPI.encryptor().decrypt(type.getEncryptedPassword()));
      }
    } catch (EncryptionException e) {
      log.warn("Encountered an ESAPI encryption exception. Check your ESAPI configuration.", e);
    }
   
    return type;
  }

  @Override
  public void store(RemoteProviderType remoteProviderType) {
    remoteProviderTypeDao.saveOrUpdate(remoteProviderType);
  }
 
  @Override
  public ResponseCode checkConfiguration(String username, String password, String apiKey, String matchSourceNumber,
                                           String platform, int typeId) {
   
    RemoteProviderType databaseRemoteProviderType = load(typeId);

        boolean matchSourceNumberBoolean = "true".equals(matchSourceNumber);

    if (databaseRemoteProviderType == null) {
      return ResponseCode.BAD_ID;
    }
   
    databaseRemoteProviderType = decryptCredentials(databaseRemoteProviderType);
   
    // TODO test this
    // If the username hasn't changed but the password has, update the apps instead of deleting them.
   
    if (databaseRemoteProviderType.getHasUserNamePassword() &&
        username != null && password != null &&
        username.equals(databaseRemoteProviderType.getUsername()) &&
        !password.equals(USE_OLD_PASSWORD) &&
        !password.equals(databaseRemoteProviderType.getPassword())) {
     
      log.warn("Provider password has changed, updating applications.");
     
      databaseRemoteProviderType.setPassword(password);
      databaseRemoteProviderType.setPlatform(platform);
            databaseRemoteProviderType.setMatchSourceNumbers(matchSourceNumberBoolean);
      remoteProviderApplicationService.updateApplications(databaseRemoteProviderType);
      store(databaseRemoteProviderType);
      return ResponseCode.SUCCESS;
     
    } else if (databaseRemoteProviderType.getHasApiKey() &&
        apiKey != null && !apiKey.startsWith(USE_OLD_PASSWORD) &&
        !apiKey.equals(databaseRemoteProviderType.getApiKey())
        ||
        databaseRemoteProviderType.getHasUserNamePassword() &&
        username != null &&
        !username.equals(databaseRemoteProviderType.getUsername())) {
     
      databaseRemoteProviderType.setApiKey(apiKey);
      databaseRemoteProviderType.setUsername(username);
      databaseRemoteProviderType.setPassword(password);
            databaseRemoteProviderType.setPlatform(platform);
            databaseRemoteProviderType.setMatchSourceNumbers(matchSourceNumberBoolean);

            List<RemoteProviderApplication> apps = remoteProviderApplicationService
                          .getApplications(databaseRemoteProviderType);
     
      if (apps == null) {
       
        return ResponseCode.NO_APPS;

      } else {
        log.warn("Provider username has changed, deleting old apps.");
       
        remoteProviderApplicationService.deleteApps(databaseRemoteProviderType);

        databaseRemoteProviderType.setRemoteProviderApplications(apps);
       
        for (RemoteProviderApplication remoteProviderApplication :
            databaseRemoteProviderType.getRemoteProviderApplications()) {
          remoteProviderApplicationService.store(remoteProviderApplication);
        }
               
        store(encryptCredentials(databaseRemoteProviderType));
        return ResponseCode.SUCCESS;
      }
    } else if (databaseRemoteProviderType.getMatchSourceNumbers() == null ||
                databaseRemoteProviderType.getMatchSourceNumbers() != matchSourceNumberBoolean) {

            databaseRemoteProviderType.setMatchSourceNumbers(matchSourceNumberBoolean);
            store(databaseRemoteProviderType);
            return ResponseCode.SUCCESS;

        } else {
      log.info("No change was made to the credentials.");
      return ResponseCode.SUCCESS;
    }
  }

  @Override
  public void clearConfiguration(int id) {
    RemoteProviderType type = load(id);
   
    if (type != null) {
      type.setEncrypted(false);
      type.setEncryptedApiKey(null);
      type.setEncryptedUsername(null);
      type.setEncryptedPassword(null);
      if (type.getRemoteProviderApplications() != null) {
        remoteProviderApplicationService.deleteApps(type);
      }
     
      store(type);
    }
  }
}
TOP

Related Classes of com.denimgroup.threadfix.service.RemoteProviderTypeServiceImpl

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.