Skip to content

Commit 792a7da

Browse files
authored
NIGH-152 Log Findings to CircleCI UI + Make Github Token Optional (#40)
* make github token optional and log findings to circle * wip * fix bug caused by comments on outdated code * uncomment * add outdated comment to test * add info log statement if github token not given * fix auto-import syntax
1 parent eed4e3a commit 792a7da

File tree

5 files changed

+202
-15
lines changed

5 files changed

+202
-15
lines changed

cmd/nightfalldlp/main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@ func CreateDiffReviewerClient() (diffreviewer.DiffReviewer, error) {
9090
return github.NewAuthenticatedGithubService(githubToken), nil
9191
case usingCircleCi():
9292
githubToken, ok := os.LookupEnv(githubTokenEnvVar)
93-
if !ok {
94-
return nil, fmt.Errorf("could not find required %s environment variable", githubTokenEnvVar)
93+
if !ok || githubToken == "" {
94+
circleService := circleci.NewCircleCiService()
95+
circleService.GetLogger().Info("Github Token not found - findings will only be posted to CircleCI UI")
96+
return circleService, nil
9597
}
96-
return circleci.NewCircleCiService(githubToken), nil
98+
return circleci.NewCircleCiServiceWithGithubComments(githubToken), nil
9799
default:
98100
return nil, errors.New("current environment unknown")
99101
}

internal/clients/diffreviewer/circleci/circleci_service.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ const (
3939
GithubCommentRightSide = "RIGHT"
4040
)
4141

42+
var errSensitiveItemsFound = errors.New("potentially sensitive items found")
43+
4244
// Service contains the github client that makes Github api calls
4345
type Service struct {
4446
GithubClient githubintf.GithubClient
@@ -55,7 +57,14 @@ type prDetails struct {
5557
}
5658

5759
// NewCircleCiService creates a new CircleCi service
58-
func NewCircleCiService(token string) diffreviewer.DiffReviewer {
60+
func NewCircleCiService() diffreviewer.DiffReviewer {
61+
return &Service{
62+
Logger: circlelogger.NewDefaultCircleLogger(),
63+
}
64+
}
65+
66+
// NewCircleCiServiceWithGithubComments creates a new CircleCi service with an authenticated Github client
67+
func NewCircleCiServiceWithGithubComments(token string) diffreviewer.DiffReviewer {
5968
return &Service{
6069
GithubClient: gc.NewAuthenticatedClient(token),
6170
Logger: circlelogger.NewDefaultCircleLogger(),
@@ -198,6 +207,10 @@ func (s *Service) WriteComments(comments []*diffreviewer.Comment) error {
198207
s.Logger.Info("no sensitive items found")
199208
return nil
200209
}
210+
s.logCommentsToCircle(comments)
211+
if s.GithubClient == nil {
212+
return errSensitiveItemsFound
213+
}
201214
if s.PrDetails.PrNumber != nil {
202215
existingComments, _, err := s.GithubClient.PullRequestsService().ListComments(
203216
context.Background(),
@@ -221,7 +234,6 @@ func (s *Service) WriteComments(comments []*diffreviewer.Comment) error {
221234
)
222235
if err != nil {
223236
s.Logger.Error(fmt.Sprintf("Error writing comment to pull request: %s", err.Error()))
224-
s.Logger.Error(*c.Body) // log comment that was not written to circle ui
225237
}
226238
}
227239
} else {
@@ -236,12 +248,22 @@ func (s *Service) WriteComments(comments []*diffreviewer.Comment) error {
236248
)
237249
if err != nil {
238250
s.Logger.Error(fmt.Sprintf("Error writing comment to commit: %s", err.Error()))
239-
s.Logger.Error(*c.Body)
240251
}
241252
}
242253
}
243254
// returning error to fail circleCI step
244-
return errors.New("potentially sensitive items found")
255+
return errSensitiveItemsFound
256+
}
257+
258+
func (s *Service) logCommentsToCircle(comments []*diffreviewer.Comment) {
259+
for _, comment := range comments {
260+
s.Logger.Error(fmt.Sprintf(
261+
"%s at %s on line %d",
262+
comment.Body,
263+
comment.FilePath,
264+
comment.LineNumber,
265+
))
266+
}
245267
}
246268

247269
func (s *Service) createGithubPullRequestComments(comments []*diffreviewer.Comment) []*github.PullRequestComment {

internal/clients/diffreviewer/circleci/circleci_service_test.go

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@ package circleci
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"net/http/httptest"
87
"os"
98
"path"
109
"testing"
1110

12-
"github.com/nightfallai/nightfall_code_scanner/internal/mocks/clients/githubpullrequests_mock"
13-
1411
"github.com/golang/mock/gomock"
1512
"github.com/google/go-github/v31/github"
1613
"github.com/nightfallai/nightfall_code_scanner/internal/clients/diffreviewer"
1714
circlelogger "github.com/nightfallai/nightfall_code_scanner/internal/clients/logger/circle_logger"
1815
"github.com/nightfallai/nightfall_code_scanner/internal/mocks/clients/gitdiff_mock"
1916
"github.com/nightfallai/nightfall_code_scanner/internal/mocks/clients/githubclient_mock"
17+
"github.com/nightfallai/nightfall_code_scanner/internal/mocks/clients/githubpullrequests_mock"
2018
"github.com/nightfallai/nightfall_code_scanner/internal/mocks/clients/githubrepositories_mock"
19+
logger_mock "github.com/nightfallai/nightfall_code_scanner/internal/mocks/logger"
2120
"github.com/nightfallai/nightfall_code_scanner/internal/nightfallconfig"
2221
nightfallAPI "github.com/nightfallai/nightfall_go_client/generated"
2322
"github.com/stretchr/testify/suite"
@@ -226,15 +225,77 @@ func (c *circleCiTestSuite) TestGetDiff() {
226225
c.Equal(expectedFileDiffs, fileDiffs, "invalid fileDiff return value")
227226
}
228227

228+
func (c *circleCiTestSuite) TestWriteCircleComments() {
229+
tp := c.initTestParams()
230+
ctrl := gomock.NewController(c.T())
231+
defer ctrl.Finish()
232+
mockLogger := logger_mock.NewLogger(ctrl)
233+
testCircleService := &Service{
234+
Logger: mockLogger,
235+
PrDetails: prDetails{
236+
CommitSha: commitSha,
237+
Owner: testOwner,
238+
Repo: testRepo,
239+
},
240+
}
241+
tp.cs = testCircleService
242+
243+
testComments, _ := makeTestGithubRepositoryComments(
244+
"testComment",
245+
"/comments.txt",
246+
tp.cs.PrDetails.CommitSha,
247+
60,
248+
)
249+
emptyComments := []*diffreviewer.Comment{}
250+
251+
tests := []struct {
252+
giveComments []*diffreviewer.Comment
253+
wantErr error
254+
desc string
255+
}{
256+
{
257+
giveComments: testComments,
258+
wantErr: errSensitiveItemsFound,
259+
desc: "single batch comments test",
260+
},
261+
{
262+
giveComments: emptyComments,
263+
wantErr: nil,
264+
desc: "no comments test",
265+
},
266+
}
267+
268+
for _, tt := range tests {
269+
if len(tt.giveComments) == 0 {
270+
mockLogger.EXPECT().Info("no sensitive items found")
271+
}
272+
for _, comment := range tt.giveComments {
273+
mockLogger.EXPECT().Error(fmt.Sprintf(
274+
"%s at %s on line %d",
275+
comment.Body,
276+
comment.FilePath,
277+
comment.LineNumber,
278+
))
279+
}
280+
err := tp.cs.WriteComments(tt.giveComments)
281+
if len(tt.giveComments) == 0 {
282+
c.NoError(err, fmt.Sprintf("unexpected error writing comments for %s test", tt.desc))
283+
} else {
284+
c.EqualError(err, tt.wantErr.Error(), fmt.Sprintf("invalid error writing comments for %s test", tt.desc))
285+
}
286+
}
287+
}
288+
229289
func (c *circleCiTestSuite) TestWritePullRequestComments() {
230290
tp := c.initTestParams()
231291
ctrl := gomock.NewController(c.T())
232292
defer ctrl.Finish()
233293
mockClient := githubclient_mock.NewGithubClient(tp.ctrl)
234294
mockPullRequests := githubpullrequests_mock.NewGithubPullRequests(tp.ctrl)
295+
mockLogger := logger_mock.NewLogger(ctrl)
235296
testCircleService := &Service{
236297
GithubClient: mockClient,
237-
Logger: circlelogger.NewDefaultCircleLogger(),
298+
Logger: mockLogger,
238299
PrDetails: prDetails{
239300
CommitSha: commitSha,
240301
Owner: testOwner,
@@ -261,7 +322,7 @@ func (c *circleCiTestSuite) TestWritePullRequestComments() {
261322
{
262323
giveComments: testComments,
263324
giveGithubComments: testGithubComments,
264-
wantError: errors.New("potentially sensitive items found"),
325+
wantError: errSensitiveItemsFound,
265326
desc: "single batch comments test",
266327
},
267328
{
@@ -281,6 +342,9 @@ func (c *circleCiTestSuite) TestWritePullRequestComments() {
281342
*testCircleService.PrDetails.PrNumber,
282343
&github.PullRequestListCommentsOptions{},
283344
)
345+
if len(tt.giveComments) == 0 {
346+
mockLogger.EXPECT().Info("no sensitive items found")
347+
}
284348
for _, gc := range tt.giveGithubComments {
285349
mockClient.EXPECT().PullRequestsService().Return(mockPullRequests)
286350
mockPullRequests.EXPECT().CreateComment(
@@ -290,6 +354,12 @@ func (c *circleCiTestSuite) TestWritePullRequestComments() {
290354
*testCircleService.PrDetails.PrNumber,
291355
gc,
292356
)
357+
mockLogger.EXPECT().Error(fmt.Sprintf(
358+
"%s at %s on line %d",
359+
gc.GetBody(),
360+
gc.GetPath(),
361+
gc.GetLine(),
362+
))
293363
}
294364
err := tp.cs.WriteComments(tt.giveComments)
295365
if len(tt.giveComments) > 0 {
@@ -336,9 +406,10 @@ func (c *circleCiTestSuite) TestWriteRepositoryComments() {
336406
defer ctrl.Finish()
337407
mockClient := githubclient_mock.NewGithubClient(tp.ctrl)
338408
mockRepositories := githubrepositories_mock.NewGithubRepositories(tp.ctrl)
409+
mockLogger := logger_mock.NewLogger(ctrl)
339410
testCircleService := &Service{
340411
GithubClient: mockClient,
341-
Logger: circlelogger.NewDefaultCircleLogger(),
412+
Logger: mockLogger,
342413
PrDetails: prDetails{
343414
CommitSha: commitSha,
344415
Owner: testOwner,
@@ -364,7 +435,7 @@ func (c *circleCiTestSuite) TestWriteRepositoryComments() {
364435
{
365436
giveComments: testComments,
366437
giveGithubComments: testGithubComments,
367-
wantError: errors.New("potentially sensitive items found"),
438+
wantError: errSensitiveItemsFound,
368439
desc: "single batch comments test",
369440
},
370441
{
@@ -376,7 +447,10 @@ func (c *circleCiTestSuite) TestWriteRepositoryComments() {
376447
}
377448

378449
for _, tt := range tests {
379-
for _, gc := range tt.giveGithubComments {
450+
if len(tt.giveGithubComments) == 0 {
451+
mockLogger.EXPECT().Info("no sensitive items found")
452+
}
453+
for index, gc := range tt.giveGithubComments {
380454
mockClient.EXPECT().RepositoriesService().Return(mockRepositories)
381455
mockRepositories.EXPECT().CreateComment(
382456
context.Background(),
@@ -385,6 +459,12 @@ func (c *circleCiTestSuite) TestWriteRepositoryComments() {
385459
testCircleService.PrDetails.CommitSha,
386460
gc,
387461
)
462+
mockLogger.EXPECT().Error(fmt.Sprintf(
463+
"%s at %s on line %d",
464+
gc.GetBody(),
465+
gc.GetPath(),
466+
tt.giveComments[index].LineNumber,
467+
))
388468
}
389469
err := tp.cs.WriteComments(tt.giveComments)
390470
if len(tt.giveComments) > 0 {

internal/clients/logger/logger.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package logger
22

3+
//go:generate go run github.com/golang/mock/mockgen -destination=../../mocks/logger/logger_mock.go -source=../logger/logger.go -package=logger_mock -mock_names=Logger=Logger
4+
35
// Logger is the interface for logging content
46
type Logger interface {
57
Debug(msg string)

internal/mocks/logger/logger_mock.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)