private IssueAnnotation[] ProcessRemainingIssues(PostProcessingBundle bundle)
        {
            var remainingIssues = bundle.IssueAnnotations
                                  .Where(x => bundle.IssueVulnerabilityLinks.All(y => y.IssueAnnotation != x)).ToList();

            // fixed
            // ReSharper disable once LoopCanBePartlyConvertedToQuery
            foreach (var issueAnnotation in remainingIssues.ToArray())
            {
                if ((issueAnnotation.State == IssueAnnotationState.Fixed) ||
                    (issueAnnotation.State == IssueAnnotationState.FalsePositive))
                {
                    continue;
                }

                remainingIssues.Remove(issueAnnotation);

                _issueAnnotationWorkflow.ChangeState(issueAnnotation, IssueAnnotationState.Fixed);

                bundle.Changes.Add(new FileChangeAnnotation
                {
                    Annotation = issueAnnotation,
                    Type       = FileChangeAnnotationType.Update
                });
            }

            return(remainingIssues.ToArray());
        }
Example #2
0
        protected override void ExecuteStage(PostProcessingBundle bundle) =>
        bundle.VulnerabilitiesInfo = bundle.VulnerabilitiesInfo
                                     .GroupBy(x => new { x.Place, x.Type })
                                     .Select(
            x =>
            x.Any(y => !string.IsNullOrWhiteSpace(y.Exploit))
                                                        ? x.FirstOrDefault(y => !string.IsNullOrWhiteSpace(y.Exploit))
                                                        : x.First())
                                     .Select(x =>
        {
            var splittedPlace = x.Place.Split(':');

            string file;

            if (splittedPlace.Length > 2)
            {
                file = string.Join(":", splittedPlace.Take(splittedPlace.Length - 3));

                x.Position = int.Parse(splittedPlace[splittedPlace.Length - 2]);
            }
            else
            {
                file = x.Place;
            }

            file = file.Substring(bundle.Task.FolderPath.Length).Trim('\\');

            x.File = x.SourceFile = file;

            return(x);
        }).ToArray();
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            if (bundle.Task.Projects.VcsPluginId == null)
            {
                throw new Exception();
            }

            bundle.VersionControlPlugin = _backendPluginProvider.GetPlugin <IVersionControlPlugin>(
                bundle.Task.Projects.VcsPluginId.Value,
                bundle.Task.CreatedById,
                bundle.Task.ProjectId);
        }
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            if (bundle.Task.Projects.ItPluginId == null)
            {
                throw new Exception("Project IT plugin is not initialized.");
            }

            bundle.IssueTrackerPlugin = _backendPluginProvider.GetPlugin <IIssueTrackerPlugin>(
                bundle.Task.Projects.ItPluginId.Value,
                bundle.Task.CreatedById,
                bundle.Task.ProjectId);
        }
        public void Execute([NotNull] PostProcessingBundle bundle)
        {
            if (bundle == null)
            {
                throw new ArgumentNullException(nameof(bundle));
            }

            if (PreCondition.Invoke(bundle.Task))
            {
                ExecuteStage(bundle);
            }

            ExecuteSuccessor(bundle);
        }
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            if (!_branchNameBuilder.IsOurBranch(bundle.Task.Repository))
            {
                return;
            }

            var branchVulnerabilityTypeName = _branchNameBuilder.GetInfo(bundle.Task.Repository);

            bundle.VulnerabilitiesInfo = bundle.VulnerabilitiesInfo
                                         .Where(x => x.Type.ToLower() == branchVulnerabilityTypeName.Type)
                                         .ToArray();

            bundle.IssueAnnotations = bundle.IssueAnnotations
                                      .Where(x => x.LongName.ToLower() == branchVulnerabilityTypeName.Type)
                                      .ToArray();
        }
 protected override void ExecuteStage([NotNull] PostProcessingBundle bundle) =>
 bundle.VulnerabilitiesInfo = _vulnerabilityInfoProvider.GetByTask(bundle.Task);
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            var fpAnnotation =
                bundle.IssueVulnerabilityLinks
                .Select(x => x.IssueAnnotation)
                .Concat(bundle.RemainingIssues)
                .Where(x => x.State == IssueAnnotationState.FalsePositive)
                .ToArray();

            var fixedAnnotation = bundle.RemainingIssues
                                  .Concat(bundle.Changes.Where(x => x.Type == FileChangeAnnotationType.Update).Select(x => x.Annotation))
                                  .Where(x => x.State == IssueAnnotationState.Fixed)
                                  .ToArray();

            var todoVulnerabilities   = bundle.Changes.Where(x => x.Annotation.State == IssueAnnotationState.Todo).ToArray();
            var reopenVulnerabilities = bundle.Changes.Where(x => x.Annotation.State == IssueAnnotationState.Reopen).ToArray();

            var groups =
                fpAnnotation.Select(x => new { Type = x.LongName, IssueId = x.Id })
                .Concat(
                    fixedAnnotation.Select(
                        x => new
            {
                Type    = x.LongName,
                IssueId = x.Id
            }))
                .Concat(
                    todoVulnerabilities.Concat(reopenVulnerabilities)
                    .Select(x => new { Type = x.Annotation.LongName, IssueId = x.Annotation.Id }))
                .Distinct()
                .ToArray();

            foreach (var group in groups)
            {
                var branchName = _branchNameBuilder.Build(new BranchNameBuilderInfo {
                    Type = group.Type
                });

                var template = _templateProvider.Get(TemplateNames.IssueBody);

                var fp = fpAnnotation.Where(x => x.LongName == group.Type).GroupBy(
                    x => new
                {
                    x.File,
                    x.LineStart
                }).Select(x => x.First()).ToArray();

                var fixedItems = fixedAnnotation.Where(x => x.LongName == group.Type).GroupBy(
                    x => new
                {
                    x.File,
                    x.LineStart
                }).Select(x => x.First()).ToArray();

                var todoItems = todoVulnerabilities
                                .Where(x => x.Annotation.LongName == group.Type)
                                .GroupBy(
                    x => new
                {
                    x.Vulnerability.File,
                    x.Vulnerability.NumberLine
                }).Select(x => x.First()).ToArray();

                var reopenItems = reopenVulnerabilities
                                  .Where(x => x.Annotation.LongName == group.Type)
                                  .GroupBy(
                    x => new
                {
                    x.Vulnerability.File,
                    x.Vulnerability.NumberLine
                }).Select(x => x.First()).ToArray();

                template.Body.Add(
                    new Dictionary <string, object>
                {
                    {
                        "FP", fp
                    },
                    {
                        "Fixed", fixedItems
                    },
                    {
                        "Todo", todoItems
                    },
                    {
                        "Reopen", reopenItems
                    },

                    // TODO: remove code block cause incorrect read out strongly typed GitHub settings
                    //{
                    //	"RepoOwner", settings[GitHubItSettingKeys.RepositoryOwner.ToString()]
                    //},
                    //{
                    //	"RepoName", settings[GitHubItSettingKeys.RepositoryName.ToString()]
                    //},
                    {
                        "RepoBranch", branchName
                    },
                    {
                        "TotalCount", fp.Length + fixedItems.Length + todoItems.Length + reopenItems.Length
                    }
                });

                var body = template.Body.Render();

                var issue = bundle.Issues.FirstOrDefault(x => x.Id == group.IssueId) ??
                            bundle.IssueTrackerPlugin.GetIssue(group.IssueId);

                var title = _issueNameBuilder.Build(
                    new IssueNameBuilderInfo
                {
                    IssueTypeName = group.Type
                });

                if (fp.Any() || fixedItems.Any() || todoItems.Any() || reopenItems.Any())
                {
                    title += Resources.IssueNameLeft.FormatWith(todoItems.Length + reopenItems.Length);
                }

                using (var telemetryScope = _telemetryScopeProvider.Create <ItPluginInfo>(TelemetryOperationNames.ItPlugin.Update))
                {
                    try
                    {
                        telemetryScope.SetEntity(
                            new ItPluginInfo
                        {
                            Plugins = bundle.Task.Projects.Plugins,
                            TaskId  = bundle.Task.Id
                        });

                        bundle.IssueTrackerPlugin.UpdateIssue(
                            new UpdateIssueRequest
                        {
                            Id          = issue.Id,
                            Title       = title,
                            Description = body,
                            Status      =
                                todoVulnerabilities.Concat(reopenVulnerabilities).Any(x => x.Annotation.LongName == group.Type)
                                                                                        ? IssueStatus.Open
                                                                                        : IssueStatus.Closed
                        });

                        telemetryScope.WriteSuccess();
                    }
                    catch (Exception ex)
                    {
                        telemetryScope.WriteException(ex);

                        throw;
                    }
                }
            }
        }
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            var vulnerabilityTypeGroups = bundle.VulnerabilitiesInfo
                                          .Where(x => bundle.IssueVulnerabilityLinks.All(y => y.VulnerabilityInfo != x))
                                          .GroupBy(x => x.Type);

            // new
            foreach (var vulnerabilityGroup in vulnerabilityTypeGroups)
            {
                var issueTitle = _issueNameBuilder.Build(
                    new IssueNameBuilderInfo
                {
                    IssueTypeName = vulnerabilityGroup.Key
                });

                Issue itIssue = null;

                if (bundle.Task.Projects.CommitToIt)
                {
                    itIssue = bundle.Issues.FirstOrDefault(
                        x =>
                        x.Title.StartsWith(
                            issueTitle,
                            StringComparison.InvariantCultureIgnoreCase));

                    if (itIssue == null)
                    {
                        using (var telemetryScope = _telemetryScopeProvider.Create <ItPluginInfo>(TelemetryOperationNames.ItPlugin.Create))
                        {
                            try
                            {
                                telemetryScope.SetEntity(
                                    new ItPluginInfo
                                {
                                    Plugins = bundle.Task.Projects.Plugins,
                                    TaskId  = bundle.Task.Id
                                });

                                itIssue = bundle.IssueTrackerPlugin.CreateIssue(
                                    bundle.Task.Repository,
                                    new CreateIssueRequest
                                {
                                    Title       = issueTitle,
                                    Description = string.Empty
                                });

                                telemetryScope.WriteSuccess();
                            }
                            catch (Exception ex)
                            {
                                telemetryScope.WriteException(ex);

                                throw;
                            }
                        }
                    }
                }

                //bundle.Issues.Add(itIssue); TODO: wtf its here?

                foreach (var vulnerabilityInfo in vulnerabilityGroup)
                {
                    vulnerabilityInfo.IssueNumber = itIssue?.Id;
                    vulnerabilityInfo.IssueUrl    = itIssue?.Url;

                    var additionalContent = string.Empty;

                    if (!string.IsNullOrWhiteSpace(vulnerabilityInfo.Exploit))
                    {
                        additionalContent += "\n" + vulnerabilityInfo.Exploit;
                    }

                    if (!string.IsNullOrWhiteSpace(vulnerabilityInfo.AdditionalExploitConditions))
                    {
                        additionalContent += "\n" + vulnerabilityInfo.AdditionalExploitConditions;
                    }

                    var issue = new IssueAnnotation
                    {
                        LineStart         = vulnerabilityInfo.NumberLine,
                        File              = vulnerabilityInfo.File,
                        LongName          = vulnerabilityInfo.Type,
                        Severity          = "High",
                        Id                = itIssue?.Id,
                        IssuePath         = itIssue?.Url,
                        AdditionalContent = additionalContent
                    };

                    bundle.Changes.Add(new FileChangeAnnotation
                    {
                        Annotation    = issue,
                        Vulnerability = vulnerabilityInfo,
                        Type          = FileChangeAnnotationType.Add
                    });
                }
            }
        }
Example #10
0
 protected override void ExecuteStage(PostProcessingBundle bundle) =>
 bundle.Issues = bundle.IssueTrackerPlugin.GetIssues().ToList();
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            var branches = bundle.VersionControlPlugin.GetBranches().ToList();

            var mainBranch = branches.First(x => x.Name == bundle.Task.Repository);

            var annotationGroups = bundle.Changes
                                   .Where(x => x.Type != FileChangeAnnotationType.None)
                                   .GroupBy(x => x.Annotation.LongName);

            foreach (var typeGroup in annotationGroups)
            {
                var branchName = _branchNameBuilder.Build(new BranchNameBuilderInfo {
                    Type = typeGroup.Key
                });

                var branch = branches.FirstOrDefault(
                    x => string.Equals(
                        x.Name,
                        branchName,
                        StringComparison.CurrentCultureIgnoreCase));

                if (branch == null)
                {
                    using (
                        var telemetryScope = _telemetryScopeProvider.Create <VcsPluginInfo>(TelemetryOperationNames.VcsPlugin.CreateBranch)
                        )
                    {
                        try
                        {
                            telemetryScope.SetEntity(
                                new VcsPluginInfo
                            {
                                Plugin            = bundle.Task.Projects.Plugins1,                              // VCS plugin =)
                                CreatedBranchName = branchName,
                                TaskId            = bundle.Task.Id
                            });

                            branch = bundle.VersionControlPlugin.CreateBranch(bundle.Task.FolderPath, branchName, mainBranch.Id);

                            telemetryScope.WriteSuccess();
                        }
                        catch (Exception ex)
                        {
                            telemetryScope.WriteException(ex);

                            throw;
                        }
                    }

                    branches.Add(branch);
                }

                foreach (var fileGroup in typeGroup.GroupBy(x => x.Annotation.File))
                {
                    var content = File.ReadAllText(Path.Combine(bundle.Task.FolderPath, fileGroup.Key));

                    var ending = content.GetLineSplitter();

                    var linesContent = content.Split(new[] { ending }, StringSplitOptions.None).ToList();

                    var rowShift = 0;

                    foreach (var fileUpdate in fileGroup.OrderBy(x => x.Annotation.LineStart))
                    {
                        var removeCount = 0;

                        if (fileUpdate.Type == FileChangeAnnotationType.Update)
                        {
                            removeCount = fileUpdate.Annotation.LineEnd - fileUpdate.Annotation.LineStart + 1;

                            for (var index = 0; index < removeCount; index++)
                            {
                                linesContent.RemoveAt(fileUpdate.Annotation.LineStart + rowShift - 1);
                            }
                        }

                        var serializedIssueAnnotation = _issueAnnotationSerializer.Serialize(fileUpdate.Annotation);

                        var annotation = _issueAnnotationFormatter.Format(serializedIssueAnnotation);

                        var lines = annotation.Split('\n');

                        var rawLine        = linesContent[fileUpdate.Annotation.LineStart + rowShift - 1];
                        var startLineShift = rawLine.Substring(0, rawLine.Length - rawLine.TrimStart(' ', '\t').Length);

                        for (var index = 0; index < lines.Length; index++)
                        {
                            linesContent.Insert(
                                fileUpdate.Annotation.LineStart + rowShift + index - 1,
                                startLineShift + lines[index].Trim());
                        }

                        rowShift = rowShift - removeCount + lines.Length;
                        if (fileUpdate.Vulnerability != null)
                        {
                            fileUpdate.Vulnerability.NumberLine = fileUpdate.Annotation.LineStart + rowShift;
                        }
                    }

                    var memoryStream = new MemoryStream();
                    var streamWriter = new StreamWriter(memoryStream);

                    streamWriter.Write(string.Join(ending, linesContent));

                    streamWriter.Flush();
                    streamWriter.Close();

                    var commitTemplate = _templateProvider.Get(TemplateNames.CommitName);

                    commitTemplate.Body.Add(
                        new Dictionary <string, object>
                    {
                        { "Group", _vulnerabilityShortTypeResolver.Resolve(typeGroup.Key) },
                        { "File", Path.GetFileName(fileGroup.Key) }
                    });

                    var bodyCommit = commitTemplate.Body.Render();

                    _log.Debug($"Commit to {branch.Id} {fileGroup.Key}");

                    var fileContent = memoryStream.ToArray();

                    using (var telemetryScope = _telemetryScopeProvider.Create <VcsPluginInfo>(TelemetryOperationNames.VcsPlugin.Commit))
                    {
                        try
                        {
                            telemetryScope.SetEntity(
                                new VcsPluginInfo
                            {
                                Plugin = bundle.Task.Projects.Plugins1,                                         // VCS plugin
                                CommittedSourcesSize = fileContent.Length,
                                TaskId = bundle.Task.Id
                            });

                            bundle.VersionControlPlugin.Commit(
                                bundle.Task.FolderPath,
                                branch.Id,
                                bodyCommit,
                                fileGroup.Key,
                                fileContent);

                            telemetryScope.WriteSuccess();
                        }
                        catch (Exception ex)
                        {
                            telemetryScope.WriteException(ex);

                            throw;
                        }
                    }
                }
            }

            bundle.VersionControlPlugin.CleanUp(bundle.Task.FolderPath);
        }
Example #12
0
 protected override void ExecuteStage(PostProcessingBundle bundle)
 => bundle.IssueAnnotations = GetIssuesByTask(bundle.Task);
Example #13
0
        protected override void ExecuteStage(PostProcessingBundle bundle)
        {
            var pairs = new List <IssueVulnerabilityLink>();

            var vulnGroups = bundle.VulnerabilitiesInfo
                             .GroupBy(x => x.Type)
                             .ToDictionary(x => x.Key, x => x.ToArray());

            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var issueAnnotation in bundle.IssueAnnotations)
            {
                if (!vulnGroups.ContainsKey(issueAnnotation.LongName))
                {
                    continue;
                }

                var vulns         = vulnGroups[issueAnnotation.LongName];
                var vulnerability =
                    vulns
                    .Where(x => x.File == issueAnnotation.File)
                    .FirstOrDefault(x => issueAnnotation.LineEnd + 1 == x.NumberLine);
                if (vulnerability == null)
                {
                    continue;
                }

                vulnerability.IssueNumber = issueAnnotation.Id;
                vulnerability.IssueUrl    = issueAnnotation.IssuePath;

                pairs.Add(new IssueVulnerabilityLink(issueAnnotation, vulnerability));
            }

            // reopen or fp
            // ReSharper disable once LoopCanBePartlyConvertedToQuery
            foreach (var pair in pairs)
            {
                // ignoring false positives
                if (pair.IssueAnnotation.State == IssueAnnotationState.FalsePositive)
                {
                    continue;
                }

                // Don't process not finished issues
                if ((pair.IssueAnnotation.State != IssueAnnotationState.Verify) &&
                    (pair.IssueAnnotation.State != IssueAnnotationState.Fixed))
                {
                    bundle.Changes.Add(new FileChangeAnnotation
                    {
                        Annotation    = pair.IssueAnnotation,
                        Vulnerability = pair.VulnerabilityInfo,
                        Type          =
                            pair.IssueAnnotation.State == IssueAnnotationState.Todo
                                                                ? FileChangeAnnotationType.None
                                                                : FileChangeAnnotationType.Update
                    });
                    continue;
                }

                _issueAnnotationWorkflow.ChangeState(pair.IssueAnnotation, IssueAnnotationState.Reopen);

                bundle.Changes.Add(new FileChangeAnnotation
                {
                    Annotation    = pair.IssueAnnotation,
                    Vulnerability = pair.VulnerabilityInfo,
                    Type          = FileChangeAnnotationType.Update
                });
            }

            bundle.IssueVulnerabilityLinks = pairs.ToArray();
        }
 protected override void ExecuteStage(PostProcessingBundle bundle) =>
 bundle.RemainingIssues = ProcessRemainingIssues(bundle);
 private void ExecuteSuccessor(PostProcessingBundle bundle) => _successor?.Execute(bundle);
 protected abstract void ExecuteStage(PostProcessingBundle bundle);