forked from jfrog/frogbot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemail.go
133 lines (119 loc) · 4.4 KB
/
email.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package utils
import (
"context"
"fmt"
"github.com/jfrog/frogbot/v2/utils/outputwriter"
"github.com/jfrog/froggit-go/vcsclient"
"github.com/jfrog/froggit-go/vcsutils"
"github.com/jfrog/jfrog-cli-security/formats"
"github.com/jordan-wright/email"
"net/smtp"
"strings"
)
var blacklistedEmailAddresses = []string{"no-reply", "no_reply", "noreply", "no.reply", "frogbot"}
type SecretsEmailDetails struct {
gitClient vcsclient.VcsClient
gitProvider vcsutils.VcsProvider
branch string
repoName string
repoOwner string
detectedSecrets []formats.SourceCodeRow
pullRequestLink string
EmailDetails
}
func NewSecretsEmailDetails(gitClient vcsclient.VcsClient, repoConfig *Repository, secrets []formats.SourceCodeRow) *SecretsEmailDetails {
secretsEmailDetails := &SecretsEmailDetails{
gitClient: gitClient,
EmailDetails: repoConfig.EmailDetails,
gitProvider: repoConfig.GitProvider,
repoOwner: repoConfig.PullRequestDetails.Source.Owner,
repoName: repoConfig.PullRequestDetails.Source.Repository,
branch: repoConfig.PullRequestDetails.Source.Name,
detectedSecrets: secrets,
pullRequestLink: repoConfig.PullRequestDetails.URL,
}
return secretsEmailDetails
}
func AlertSecretsExposed(secretsDetails *SecretsEmailDetails) (err error) {
if len(secretsDetails.detectedSecrets) == 0 {
return
}
var relevantEmailReceivers []string
if relevantEmailReceivers, err = getRelevantEmailReceivers(secretsDetails.gitClient, secretsDetails.repoOwner, secretsDetails.repoName, secretsDetails.branch, secretsDetails.EmailReceivers); err != nil {
return
}
secretsDetails.EmailReceivers = append(secretsDetails.EmailReceivers, relevantEmailReceivers...)
emailDetails := secretsDetails.EmailDetails
emailContent := getSecretsEmailContent(secretsDetails.detectedSecrets, secretsDetails.gitProvider, secretsDetails.pullRequestLink)
sender := fmt.Sprintf("JFrog Frogbot <%s>", emailDetails.SmtpUser)
subject := outputwriter.FrogbotTitlePrefix + " Potential secrets detected"
return sendEmail(sender, subject, emailContent, emailDetails)
}
func getSecretsEmailContent(secrets []formats.SourceCodeRow, gitProvider vcsutils.VcsProvider, pullRequestLink string) string {
var tableContent strings.Builder
for _, secret := range secrets {
tableContent.WriteString(
fmt.Sprintf(outputwriter.SecretsEmailTableRow,
secret.File,
secret.StartLine,
secret.StartColumn,
secret.Snippet))
}
pullOrMergeRequest := "pull request"
if gitProvider == vcsutils.GitLab {
pullOrMergeRequest = "merge request"
}
return fmt.Sprintf(
outputwriter.SecretsEmailHTMLTemplate,
outputwriter.SecretsEmailCSS,
pullRequestLink,
pullOrMergeRequest,
tableContent.String(),
)
}
func sendEmail(sender, subject, content string, emailDetails EmailDetails) error {
e := prepareEmail(sender, subject, content, emailDetails)
smtpAuth := smtp.PlainAuth("", emailDetails.SmtpUser, emailDetails.SmtpPassword, emailDetails.SmtpServer)
return e.Send(strings.Join([]string{emailDetails.SmtpServer, emailDetails.SmtpPort}, ":"), smtpAuth)
}
func prepareEmail(sender, subject, content string, emailDetails EmailDetails) *email.Email {
e := email.NewEmail()
e.From = sender
e.To = emailDetails.EmailReceivers
e.Subject = subject
e.HTML = []byte(content)
return e
}
func getRelevantEmailReceivers(client vcsclient.VcsClient, repoOwner, repoName, branch string, emailReceivers []string) ([]string, error) {
commits, err := client.GetCommits(context.Background(), repoOwner, repoName, branch)
if err != nil {
return nil, err
}
return getEmailReceiversFromCommits(commits, emailReceivers)
}
func getEmailReceiversFromCommits(commits []vcsclient.CommitInfo, preConfiguredEmailReceivers []string) ([]string, error) {
emailReceivers := []string{}
for _, commit := range commits {
if shouldExcludeEmailAddress(commit.AuthorEmail, preConfiguredEmailReceivers) {
continue
}
emailReceivers = append(emailReceivers, commit.AuthorEmail)
}
return emailReceivers, nil
}
func shouldExcludeEmailAddress(emailAddress string, preConfiguredEmailReceivers []string) bool {
if emailAddress == "" {
return true
}
for _, blackListedEmail := range blacklistedEmailAddresses {
if strings.Contains(emailAddress, blackListedEmail) {
return true
}
}
for _, preConfiguredEmailAddress := range preConfiguredEmailReceivers {
if emailAddress == preConfiguredEmailAddress {
return true
}
}
return false
}