feat: [CODE-2312]: audit logging changes for commit, merge, create and delete branch (#2686)

* feat: [CODE-2312]: address resourcename to commit.go
* feat: [CODE-2312]: address failure due to exceeding limit on resource labels
* feat: [CODE-2312]: lint
* feat: [CODE-2312]: MERGE
* feat: [CODE-2312]: Update wire
* feat: [CODE-2312]: update ui labels
* feat: [CODE-2312]: update resource and action
* feat: [CODE-2312]: Audit log new action : bypassed
* feat: [CODE-2312]: audit log object update
* Merge branch 'main' into akp/CODE-2312
* feat: [CODE-2312]: audit logging changes for commit, merge, create and delete branch
* Merge branch 'main' into akp/CODE-2312
* Merge branch 'main' into akp/CODE-2312
* feat: [CODE-2312]: introduce parser and enclosing method
* feat: [CODE-2312]: annotate error
* feat: [CODE-2312]: name change and todo removal
* feat: [CODE-2312]: Annotate errors
* feat: [CODE-2232]: Branch Rules: UserGroup support: Create and List
pull/3571/head
Akhilesh Pandey 2024-10-08 16:20:56 +00:00 committed by Harness
parent 449435c9af
commit e3b3e983fd
9 changed files with 177 additions and 7 deletions

View File

@ -36,6 +36,7 @@ import (
"github.com/harness/gitness/app/sse"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git"
gitenum "github.com/harness/gitness/git/enum"
@ -49,6 +50,7 @@ type Controller struct {
tx dbtx.Transactor
urlProvider url.Provider
authorizer authz.Authorizer
auditService audit.Service
pullreqStore store.PullReqStore
activityStore store.PullReqActivityStore
codeCommentView store.CodeCommentView
@ -81,6 +83,7 @@ func NewController(
tx dbtx.Transactor,
urlProvider url.Provider,
authorizer authz.Authorizer,
auditService audit.Service,
pullreqStore store.PullReqStore,
pullreqActivityStore store.PullReqActivityStore,
codeCommentView store.CodeCommentView,
@ -112,6 +115,7 @@ func NewController(
tx: tx,
urlProvider: urlProvider,
authorizer: authorizer,
auditService: auditService,
pullreqStore: pullreqStore,
activityStore: pullreqActivityStore,
codeCommentView: codeCommentView,

View File

@ -17,6 +17,7 @@ package pullreq
import (
"context"
"fmt"
"strconv"
"strings"
"time"
@ -25,9 +26,11 @@ import (
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/bootstrap"
pullreqevents "github.com/harness/gitness/app/events/pullreq"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/app/services/codeowners"
"github.com/harness/gitness/app/services/instrument"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/contextutil"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git"
@ -553,6 +556,34 @@ func (c *Controller) Merge(
log.Ctx(ctx).Warn().Err(err).Msg("failed to publish PR changed event")
}
if protection.IsBypassed(violations) {
err = c.auditService.Log(ctx,
session.Principal,
audit.NewResource(
audit.ResourceTypeRepository,
sourceRepo.Identifier,
audit.RepoPath,
sourceRepo.Path,
audit.BypassedResourceType,
audit.BypassedResourceTypePullRequest,
audit.BypassedResourceName,
strconv.FormatInt(pr.Number, 10),
audit.BypassAction,
audit.BypassActionMerged,
),
audit.ActionBypassed,
paths.Parent(sourceRepo.Path),
audit.WithNewObject(audit.PullRequestObject{
PullReq: *pr,
RepoPath: sourceRepo.Path,
RuleViolations: violations,
}),
)
if err != nil {
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for merge pull request operation: %s", err)
}
}
err = c.instrumentation.Track(ctx, instrument.Event{
Type: instrument.EventTypeMergePullRequest,
Principal: session.Principal.ToPrincipalInfo(),

View File

@ -29,6 +29,7 @@ import (
"github.com/harness/gitness/app/sse"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/git"
"github.com/harness/gitness/store/database/dbtx"
@ -40,7 +41,11 @@ var WireSet = wire.NewSet(
ProvideController,
)
func ProvideController(tx dbtx.Transactor, urlProvider url.Provider, authorizer authz.Authorizer,
func ProvideController(
tx dbtx.Transactor,
urlProvider url.Provider,
authorizer authz.Authorizer,
auditService audit.Service,
pullReqStore store.PullReqStore, pullReqActivityStore store.PullReqActivityStore,
codeCommentsView store.CodeCommentView,
pullReqReviewStore store.PullReqReviewStore, pullReqReviewerStore store.PullReqReviewerStore,
@ -63,6 +68,7 @@ func ProvideController(tx dbtx.Transactor, urlProvider url.Provider, authorizer
return NewController(tx,
urlProvider,
authorizer,
auditService,
pullReqStore,
pullReqActivityStore,
codeCommentsView,

View File

@ -23,12 +23,16 @@ import (
"github.com/harness/gitness/app/api/controller"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/bootstrap"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git"
"github.com/harness/gitness/git/sha"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
)
// CommitFileAction holds file operation data.
@ -156,6 +160,34 @@ func (c *Controller) CommitFiles(ctx context.Context,
return types.CommitFilesResponse{}, nil, err
}
if protection.IsBypassed(violations) {
err = c.auditService.Log(ctx,
session.Principal,
audit.NewResource(
audit.ResourceTypeRepository,
repo.Identifier,
audit.RepoPath,
repo.Path,
audit.BypassAction,
audit.BypassActionCommitted,
audit.BypassedResourceType,
audit.BypassedResourceTypeCommit,
audit.BypassedResourceName,
commit.CommitID.String(),
),
audit.ActionBypassed,
paths.Parent(repo.Path),
audit.WithNewObject(audit.CommitObject{
CommitSHA: commit.CommitID.String(),
RepoPath: repo.Path,
RuleViolations: violations,
}),
)
}
if err != nil {
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for commit operation: %s", err)
}
return types.CommitFilesResponse{
CommitID: commit.CommitID.String(),
DryRunRulesOutput: types.DryRunRulesOutput{

View File

@ -20,8 +20,10 @@ import (
"github.com/harness/gitness/app/api/controller"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/app/services/instrument"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/git"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -107,6 +109,34 @@ func (c *Controller) CreateBranch(ctx context.Context,
return types.CreateBranchOutput{}, nil, fmt.Errorf("failed to map branch: %w", err)
}
if protection.IsBypassed(violations) {
err = c.auditService.Log(ctx,
session.Principal,
audit.NewResource(
audit.ResourceTypeRepository,
repo.Identifier,
audit.RepoPath,
repo.Path,
audit.BypassedResourceType,
audit.BypassedResourceTypeBranch,
audit.BypassedResourceName,
branch.Name,
audit.BypassAction,
audit.BypassActionCreated,
),
audit.ActionBypassed,
paths.Parent(repo.Path),
audit.WithNewObject(audit.BranchObject{
BranchName: branch.Name,
RepoPath: repo.Path,
RuleViolations: violations,
}),
)
if err != nil {
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for create branch operation: %s", err)
}
}
err = c.instrumentation.Track(ctx, instrument.Event{
Type: instrument.EventTypeCreateBranch,
Principal: session.Principal.ToPrincipalInfo(),

View File

@ -21,10 +21,14 @@ import (
"github.com/harness/gitness/app/api/controller"
"github.com/harness/gitness/app/api/usererror"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/audit"
"github.com/harness/gitness/git"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
)
// DeleteBranch deletes a repo branch.
@ -92,6 +96,34 @@ func (c *Controller) DeleteBranch(ctx context.Context,
return types.DeleteBranchOutput{}, nil, err
}
if protection.IsBypassed(violations) {
err = c.auditService.Log(ctx,
session.Principal,
audit.NewResource(
audit.ResourceTypeRepository,
repo.Identifier,
audit.RepoPath,
repo.Path,
audit.BypassedResourceType,
audit.BypassedResourceTypeBranch,
audit.BypassedResourceName,
branchName,
audit.BypassAction,
audit.BypassActionDeleted,
),
audit.ActionBypassed,
paths.Parent(repo.Path),
audit.WithNewObject(audit.BranchObject{
BranchName: branchName,
RepoPath: repo.Path,
RuleViolations: violations,
}),
)
if err != nil {
log.Ctx(ctx).Warn().Msgf("failed to insert audit log for delete branch operation: %s", err)
}
}
return types.DeleteBranchOutput{
DryRunRulesOutput: types.DryRunRulesOutput{
RuleViolations: violations,

View File

@ -31,20 +31,32 @@ var (
)
const (
RepoName = "repoName"
RepoName = "repoName"
BypassedResourceType = "bypassedResourceType"
BypassedResourceName = "bypassedResourceName"
RepoPath = "repoPath"
BypassedResourceTypePullRequest = "pull_request"
BypassedResourceTypeBranch = "branch"
BypassedResourceTypeCommit = "commit"
BypassAction = "bypass_action"
BypassActionDeleted = "deleted"
BypassActionCreated = "created"
BypassActionCommitted = "committed"
BypassActionMerged = "merged"
)
type Action string
const (
ActionCreated Action = "created"
ActionUpdated Action = "updated" // update default branch, switching default branch, updating description
ActionDeleted Action = "deleted"
ActionCreated Action = "created"
ActionUpdated Action = "updated" // update default branch, switching default branch, updating description
ActionDeleted Action = "deleted"
ActionBypassed Action = "bypassed"
)
func (a Action) Validate() error {
switch a {
case ActionCreated, ActionUpdated, ActionDeleted:
case ActionCreated, ActionUpdated, ActionDeleted, ActionBypassed:
return nil
default:
return ErrActionUndefined
@ -56,6 +68,8 @@ type ResourceType string
const (
ResourceTypeRepository ResourceType = "repository"
ResourceTypeBranchRule ResourceType = "branch_rule"
ResourceTypeBranch ResourceType = "branch"
ResourceTypePullRequest ResourceType = "pull_request"
ResourceTypeRepositorySettings ResourceType = "repository_settings"
ResourceTypeRegistry ResourceType = "registry"
ResourceTypeRegistryUpstreamProxy ResourceType = "registry_upstream_proxy"
@ -65,6 +79,8 @@ func (a ResourceType) Validate() error {
switch a {
case ResourceTypeRepository,
ResourceTypeBranchRule,
ResourceTypeBranch,
ResourceTypePullRequest,
ResourceTypeRepositorySettings,
ResourceTypeRegistry,
ResourceTypeRegistryUpstreamProxy:

View File

@ -31,6 +31,25 @@ type RepositoryObject struct {
type RegistryObject struct {
registrytypes.Registry
}
type PullRequestObject struct {
PullReq types.PullReq
RepoPath string `yaml:"repo_path"`
RuleViolations []types.RuleViolations `yaml:"rule_violations"`
}
type CommitObject struct {
CommitSHA string `yaml:"commit_sha"`
RepoPath string `yaml:"repo_path"`
RuleViolations []types.RuleViolations `yaml:"rule_violations"`
}
type BranchObject struct {
BranchName string `yaml:"branch_name"`
RepoPath string `yaml:"repo_path"`
RuleViolations []types.RuleViolations `yaml:"rule_violations"`
}
type RegistryUpstreamProxyConfigObject struct {
ID int64
RegistryID int64

View File

@ -361,7 +361,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
return nil, err
}
pullReq := migrate.ProvidePullReqImporter(provider, gitInterface, principalStore, repoStore, pullReqStore, pullReqActivityStore, transactor)
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, userGroupStore, userGroupReviewersStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, reporter4, migrator, pullreqService, listService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService, instrumentService, searchService)
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, auditService, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, userGroupStore, userGroupReviewersStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, reporter4, migrator, pullreqService, listService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService, instrumentService, searchService)
webhookConfig := server.ProvideWebhookConfig(config)
webhookStore := database.ProvideWebhookStore(db)
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)