forked from projectdiscovery/nuclei
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgithub.go
99 lines (87 loc) · 3.04 KB
/
github.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package github
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"golang.org/x/oauth2"
"github.com/google/go-github/github"
"github.com/pkg/errors"
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
"github.com/projectdiscovery/retryablehttp-go"
)
// Integration is a client for an issue tracker integration
type Integration struct {
client *github.Client
options *Options
}
// Options contains the configuration options for GitHub issue tracker client
type Options struct {
// BaseURL (optional) is the self-hosted GitHub application url
BaseURL string `yaml:"base-url" validate:"omitempty,url"`
// Username is the username of the github user
Username string `yaml:"username" validate:"required"`
// Owner is the owner name of the repository for issues.
Owner string `yaml:"owner" validate:"required"`
// Token is the token for GitHub account.
Token string `yaml:"token" validate:"required"`
// ProjectName is the name of the repository.
ProjectName string `yaml:"project-name" validate:"required"`
// IssueLabel (optional) is the label of the created issue type
IssueLabel string `yaml:"issue-label"`
// SeverityAsLabel (optional) sends the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label"`
HttpClient *retryablehttp.Client `yaml:"-"`
}
// New creates a new issue tracker integration client based on options.
func New(options *Options) (*Integration, error) {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: options.Token},
)
tc := oauth2.NewClient(ctx, ts)
// patch transport to support proxy - only http
// TODO: investigate if it's possible to reuse existing retryablehttp
if types.ProxyURL != "" {
if proxyURL, err := url.Parse(types.ProxyURL); err == nil {
tc.Transport.(*http.Transport).Proxy = http.ProxyURL(proxyURL)
}
}
client := github.NewClient(tc)
if options.BaseURL != "" {
parsed, err := url.Parse(options.BaseURL)
if err != nil {
return nil, errors.Wrap(err, "could not parse custom baseurl")
}
if !strings.HasSuffix(parsed.Path, "/") {
parsed.Path += "/"
}
client.BaseURL = parsed
}
return &Integration{client: client, options: options}, nil
}
// CreateIssue creates an issue in the tracker
func (i *Integration) CreateIssue(event *output.ResultEvent) error {
summary := format.Summary(event)
description := format.MarkdownDescription(event)
labels := []string{}
severityLabel := fmt.Sprintf("Severity: %s", event.Info.SeverityHolder.Severity.String())
if i.options.SeverityAsLabel && severityLabel != "" {
labels = append(labels, severityLabel)
}
if label := i.options.IssueLabel; label != "" {
labels = append(labels, label)
}
req := &github.IssueRequest{
Title: &summary,
Body: &description,
Labels: &labels,
Assignees: &[]string{i.options.Username},
}
_, _, err := i.client.Issues.Create(context.Background(), i.options.Owner, i.options.ProjectName, req)
return err
}