Skip to content

Commit

Permalink
Fix issue with user create/delete/update event
Browse files Browse the repository at this point in the history
Signed-off-by: stonezdj <[email protected]>
  • Loading branch information
stonezdj committed Feb 20, 2025
1 parent 4565907 commit a50e161
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 26 deletions.
32 changes: 16 additions & 16 deletions src/pkg/auditext/event/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@ import (
)

const (
createOp = "create"
updateOp = "update"
deleteOp = "delete"
resourceIDPattern = `^%v/(\d+)$`
createOp = "create"
updateOp = "update"
deleteOp = "delete"
)

// ResolveIDToNameFunc is the function to resolve the resource name from resource id
type ResolveIDToNameFunc func(string) string

type Resolver struct {
BaseURLPattern string
ResourceType string
SucceedCodes []int
ResourceType string
SucceedCodes []int
// SensitiveAttributes is the attributes that need to be redacted
SensitiveAttributes []string
// ShouldResolveName indicates if the resource name should be resolved before delete, if true, need to resolve the resource name before delete
ShouldResolveName bool
// IDToNameFunc is used to resolve the resource name from resource id
IDToNameFunc ResolveIDToNameFunc
IDToNameFunc ResolveIDToNameFunc
// ResourceIDPattern the url pattern to match the resourceID
ResourceIDPattern string
}

// PreCheck check if the event should be captured and resolve the resource name if needed, if need to resolve the resource name, return the resource name
Expand All @@ -61,9 +61,9 @@ func (e *Resolver) PreCheck(ctx context.Context, url string, method string) (cap
// for delete operation on a resource has name, need to resolve the resource id to resource name before delete
resName := ""
if capture && method == http.MethodDelete && e.ShouldResolveName {
re := regexp.MustCompile(fmt.Sprintf(resourceIDPattern, e.BaseURLPattern))
re := regexp.MustCompile(e.ResourceIDPattern)
m := re.FindStringSubmatch(url)
if len(m) == 2 && e.IDToNameFunc != nil {
if len(m) >= 2 && e.IDToNameFunc != nil {
resName = e.IDToNameFunc(m[1])
}
}
Expand Down Expand Up @@ -92,9 +92,9 @@ func (e *Resolver) Resolve(ce *commonevent.Metadata, event *event.Event) error {
case createOp:
if len(ce.ResponseLocation) > 0 {
// extract resource id from response location
re := regexp.MustCompile(fmt.Sprintf(resourceIDPattern, e.BaseURLPattern))
re := regexp.MustCompile(e.ResourceIDPattern)
m := re.FindStringSubmatch(ce.ResponseLocation)
if len(m) != 2 {
if len(m) < 2 {
return nil
}
evt.ResourceName = m[1]
Expand All @@ -107,9 +107,9 @@ func (e *Resolver) Resolve(ce *commonevent.Metadata, event *event.Event) error {
}

case deleteOp:
re := regexp.MustCompile(fmt.Sprintf(resourceIDPattern, e.BaseURLPattern))
re := regexp.MustCompile(e.ResourceIDPattern)
m := re.FindStringSubmatch(ce.RequestURL)
if len(m) != 2 {
if len(m) < 2 {
return nil
}
evt.ResourceName = m[1]
Expand All @@ -118,9 +118,9 @@ func (e *Resolver) Resolve(ce *commonevent.Metadata, event *event.Event) error {
}

case updateOp:
re := regexp.MustCompile(fmt.Sprintf(resourceIDPattern, e.BaseURLPattern))
re := regexp.MustCompile(e.ResourceIDPattern)
m := re.FindStringSubmatch(ce.RequestURL)
if len(m) != 2 {
if len(m) < 2 {
return nil
}
evt.ResourceName = m[1]
Expand Down
10 changes: 5 additions & 5 deletions src/pkg/auditext/event/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (

func TestEventResolver_PreCheck(t *testing.T) {
type fields struct {
BaseURLPattern string
ResourceType string
SucceedCodes []int
SensitiveAttributes []string
ShouldResolveName bool
IDToNameFunc ResolveIDToNameFunc
ResourceIDPattern string
}
type args struct {
ctx context.Context
Expand All @@ -40,14 +40,14 @@ func TestEventResolver_PreCheck(t *testing.T) {
wantCapture bool
wantResourceName string
}{
{"test normal", fields{BaseURLPattern: `/api/v2.0/tests`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true, IDToNameFunc: func(string) string { return "test" }}, args{context.Background(), "/api/v2.0/tests/123", "DELETE"}, true, "test"},
{"test resource name", fields{BaseURLPattern: `/api/v2.0/tests`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true, IDToNameFunc: func(string) string { return "test_resource_name" }}, args{context.Background(), "/api/v2.0/tests/234", "DELETE"}, true, "test_resource_name"},
{"test no resource name", fields{BaseURLPattern: `/api/v2.0/tests`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true}, args{context.Background(), "/api/v2.0/tests/234", "GET"}, true, ""},
{"test normal", fields{ResourceIDPattern: `/api/v2.0/tests/(\d+)`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true, IDToNameFunc: func(string) string { return "test" }}, args{context.Background(), "/api/v2.0/tests/123", "DELETE"}, true, "test"},
{"test resource name", fields{ResourceIDPattern: `/api/v2.0/tests/(\d+)`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true, IDToNameFunc: func(string) string { return "test_resource_name" }}, args{context.Background(), "/api/v2.0/tests/234", "DELETE"}, true, "test_resource_name"},
{"test no resource name", fields{ResourceIDPattern: `/api/v2.0/tests/(\d+)`, ResourceType: "test", SucceedCodes: []int{200}, ShouldResolveName: true}, args{context.Background(), "/api/v2.0/tests/234", "GET"}, true, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &Resolver{
BaseURLPattern: tt.fields.BaseURLPattern,
ResourceIDPattern: tt.fields.ResourceIDPattern,
ResourceType: tt.fields.ResourceType,
SucceedCodes: tt.fields.SucceedCodes,
SensitiveAttributes: tt.fields.SensitiveAttributes,
Expand Down
8 changes: 4 additions & 4 deletions src/pkg/auditext/event/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ import (
pkgUser "github.com/goharbor/harbor/src/pkg/user"
)

const urlPattern = `^/api/v2.0/users/(\d+)(/password|/sysadmin)?$`

func init() {
var userResolver = &userEventResolver{
Resolver: event.Resolver{
BaseURLPattern: "/api/v2.0/users",
ResourceType: rbac.ResourceUser.String(),
SucceedCodes: []int{http.StatusCreated, http.StatusOK},
SensitiveAttributes: []string{"password"},
ShouldResolveName: true,
IDToNameFunc: userIDToName,
ResourceIDPattern: urlPattern,
},
}
commonevent.RegisterResolver(`/api/v2.0/users$`, userResolver)
commonevent.RegisterResolver(`^/api/v2.0/users/\d+/password$`, userResolver)
commonevent.RegisterResolver(`^/api/v2.0/users/\d+/sysadmin$`, userResolver)
commonevent.RegisterResolver(`^/api/v2.0/users/\d+$`, userResolver)
commonevent.RegisterResolver(urlPattern, userResolver)
}

type userEventResolver struct {
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/auditext/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
beego_orm "github.com/beego/beego/v2/client/orm"
)

const OtherEvents = "other_events"
const OtherEvents = "other"

func init() {
beego_orm.RegisterModel(&AuditLogExt{})
Expand Down

0 comments on commit a50e161

Please sign in to comment.