Beispiel #1
0
        private async Task ResolveScans()
        {
            var policyTask = PopulatePolicies();

            var presetsTask = PopulatePresets();

            var teamsTask = PopulateTeams();

            _log.Debug("Resolving projects.");

            var projects = await Task.Run(() => CxProjects.GetProjects(RestContext, CancelToken), CancelToken);

            Policies = await policyTask;
            Teams    = await teamsTask;
            Presets  = await presetsTask;


            Parallel.ForEach(projects, new ParallelOptions {
                CancellationToken = CancelToken
            }, (p) =>
            {
                if (p.ProjectName == null)
                {
                    return;
                }

                String combinedPolicyNames = String.Empty;

                if (Policies != null)
                {
                    try
                    {
                        IEnumerable <int> projectPolicyList = CxMnoPolicies.GetPolicyIdsForProject
                                                                  (RestContext, CancelToken, p.ProjectId);

                        if (projectPolicyList != null)
                        {
                            Policies.CorrelateProjectToPolicies(p.ProjectId, projectPolicyList);
                            combinedPolicyNames = GetFlatPolicyNames(Policies, projectPolicyList);
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Warn($"Unable to correlate policies to project {p.ProjectId}: {p.ProjectName}. " +
                                  $"Policy statistics will be unavalable.", ex);
                    }
                }

                var cfDict = new SortedDictionary <String, String>();
                p.CustomFields.ForEach((cf) => cfDict.Add(cf.FieldName, cf.FieldValue));


                // Load the projects
                String teamName = Teams.ContainsKey(p.TeamId) ? Teams[p.TeamId] : String.Empty;
                if (String.Empty == teamName)
                {
                    _log.ErrorFormat("Unable to find a team name for team id [{0}] when adding project {1}:{2}", p.TeamId,
                                     p.ProjectId, p.ProjectName);

                    return;
                }

                String presetName = Presets.ContainsKey(p.PresetId) ? Presets[p.PresetId] : String.Empty;
                if (String.Empty == presetName)
                {
                    _log.ErrorFormat("Unable to find a preset name for preset id [{0}] " +
                                     "when adding project {1}:{2}; project may be assigned an invalid preset.", p.PresetId,
                                     p.ProjectId, p.ProjectName);

                    return;
                }


                if (!Filter.Matches(teamName, p.ProjectName))
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.Debug($"FILTERED: Team: [{teamName}] Project: [{p.ProjectName}]");
                    }

                    return;
                }

                if (!_loadedProjects.TryAdd(p.ProjectId,
                                            new ProjectDescriptor()
                {
                    ProjectId = p.ProjectId,
                    ProjectName = p.ProjectName,
                    TeamName = teamName,
                    TeamId = p.TeamId,
                    PresetId = p.PresetId,
                    PresetName = presetName,
                    Policies = combinedPolicyNames,
                    CustomFields = cfDict
                }
                                            ))
                {
                    _log.WarnFormat("Rejected changed when adding new project with duplicate id {0}: New name: [{1}] current name: [{2}].",
                                    p.ProjectId, p.ProjectName, _loadedProjects[p.ProjectId].ProjectName);

                    return;
                }
            });


            // _loadedProjects has a collection of projects loaded from the SAST system
            _state.ConfirmProjects(new List <ProjectDescriptor>(_loadedProjects.Values));

            _log.Info($"{_state.ProjectCount} projects are targets to check for new scans. Since last scan: {_state.DeletedProjects}"
                      + $" projects removed, {_state.NewProjects} new projects.");


            _log.Debug("Resolving scans.");

            // Load the scans for each project
            Parallel.ForEach(_state.Projects, new ParallelOptions {
                CancellationToken = CancelToken
            },
                             (p) =>
            {
                // SAST Scans
                var sastScans = CxSastScans.GetScans(RestContext, CancelToken, CxSastScans.ScanStatus.Finished, p.ProjectId);

                foreach (var s in sastScans)
                {
                    // Add to crawl state.
                    if (_log.IsTraceEnabled())
                    {
                        _log.Trace($"SAST scan record: {s}");
                    }
                    _state.AddScan(s.ProjectId, s.ScanType, ScanProductType.SAST, s.ScanId, s.FinishTime);
                    SastScanCache.TryAdd(s.ScanId, s);
                }

                // OSA scans
                var osaScans = CxOsaScans.GetScans(RestContext, CancelToken, p.ProjectId);
                foreach (var s in osaScans)
                {
                    // Add to crawl state.
                    if (_log.IsTraceEnabled())
                    {
                        _log.Trace($"OSA scan record: {s}");
                    }
                    _state.AddScan(s.ProjectId, "Composition", ScanProductType.SCA, s.ScanId, s.FinishTime);
                    ScaScanCache.TryAdd(s.ScanId, s);
                }
            });
        }