Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add user login event to audit log
Browse files Browse the repository at this point in the history
  Add common event handler
  Register login event
  Update previous audit log event redirect to auditlogext table

Signed-off-by: stonezdj <[email protected]>
stonezdj committed Jan 21, 2025

Verified

This commit was signed with the committer’s verified signature. The key has expired.
addaleax Anna Henningsen
1 parent 60798a4 commit 9cc4519
Showing 11 changed files with 364 additions and 99 deletions.
18 changes: 9 additions & 9 deletions src/controller/event/handler/auditlog/auditlog.go
Original file line number Diff line number Diff line change
@@ -16,12 +16,14 @@ package auditlog

import (
"context"
"fmt"

"github.com/goharbor/harbor/src/controller/event"
evtModel "github.com/goharbor/harbor/src/controller/event/model"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/audit"
am "github.com/goharbor/harbor/src/pkg/audit/model"
"github.com/goharbor/harbor/src/pkg/auditext"
am "github.com/goharbor/harbor/src/pkg/auditext/model"
)

// Handler - audit log handler
@@ -30,7 +32,7 @@ type Handler struct {

// AuditResolver - interface to resolve to AuditLog
type AuditResolver interface {
ResolveToAuditLog() (*am.AuditLog, error)
ResolveToAuditLog() (*am.AuditLogExt, error)
}

// Name ...
@@ -40,13 +42,12 @@ func (h *Handler) Name() string {

// Handle ...
func (h *Handler) Handle(ctx context.Context, value interface{}) error {
var auditLog *am.AuditLog
var addAuditLog bool
switch v := value.(type) {
case *event.PushArtifactEvent, *event.DeleteArtifactEvent,
*event.DeleteRepositoryEvent, *event.CreateProjectEvent, *event.DeleteProjectEvent,
*event.DeleteTagEvent, *event.CreateTagEvent,
*event.CreateRobotEvent, *event.DeleteRobotEvent:
*event.CreateRobotEvent, *event.DeleteRobotEvent, *evtModel.CommonEvent:
addAuditLog = true
case *event.PullArtifactEvent:
addAuditLog = !config.PullAuditLogDisable(ctx)
@@ -56,14 +57,13 @@ func (h *Handler) Handle(ctx context.Context, value interface{}) error {

if addAuditLog {
resolver := value.(AuditResolver)
al, err := resolver.ResolveToAuditLog()
auditLog, err := resolver.ResolveToAuditLog()
if err != nil {
log.Errorf("failed to handler event %v", err)
return err
}
auditLog = al
if auditLog != nil {
_, err := audit.Mgr.Create(ctx, auditLog)
if auditLog != nil && config.AuditLogEventEnabled(ctx, fmt.Sprintf("%v_%v", auditLog.Operation, auditLog.ResourceType)) {
_, err := auditext.Mgr.Create(ctx, auditLog)
if err != nil {
log.Debugf("add audit log err: %v", err)
}
1 change: 1 addition & 0 deletions src/controller/event/handler/init.go
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ func init() {
_ = notifier.Subscribe(event.TopicDeleteTag, &auditlog.Handler{})
_ = notifier.Subscribe(event.TopicCreateRobot, &auditlog.Handler{})
_ = notifier.Subscribe(event.TopicDeleteRobot, &auditlog.Handler{})
_ = notifier.Subscribe(event.TopicCommonEvent, &auditlog.Handler{})

// internal
_ = notifier.Subscribe(event.TopicPullArtifact, &internal.ArtifactEventHandler{})
4 changes: 3 additions & 1 deletion src/controller/event/metadata/commonevent/model.go
Original file line number Diff line number Diff line change
@@ -62,8 +62,10 @@ type Metadata struct {
IPAddress string
// ResponseLocation response location
ResponseLocation string
// ResourceName
// ResourceName resource name
ResourceName string
// Payload request payload
Payload string
}

// Resolve parse the audit information from CommonEventMetadata
36 changes: 35 additions & 1 deletion src/controller/event/model/event.go
Original file line number Diff line number Diff line change
@@ -14,7 +14,12 @@

package model

import "github.com/goharbor/harbor/src/pkg/retention/policy/rule"
import (
"time"

"github.com/goharbor/harbor/src/pkg/auditext/model"
"github.com/goharbor/harbor/src/pkg/retention/policy/rule"
)

// Replication describes replication infos
type Replication struct {
@@ -80,3 +85,32 @@ type Scan struct {
// ScanType the scan type
ScanType string `json:"scan_type,omitempty"`
}

// CommonEvent ...
type CommonEvent struct {
Operator string
ProjectID int64
OcurrAt time.Time
Operation string
Payload string
SourceIP string
ResourceType string
ResourceName string
OperationDescription string
IsSuccessful bool
}

// ResolveToAuditLog ...
func (c *CommonEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: c.ProjectID,
OpTime: c.OcurrAt,
Operation: c.Operation,
Username: c.Operator,
ResourceType: c.ResourceType,
Resource: c.ResourceName,
OperationDescription: c.OperationDescription,
IsSuccessful: c.IsSuccessful,
}
return auditLog, nil
}
187 changes: 106 additions & 81 deletions src/controller/event/topic.go
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ import (
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/lib/selector"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/audit/model"
"github.com/goharbor/harbor/src/pkg/auditext/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
robotModel "github.com/goharbor/harbor/src/pkg/robot/model"
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
@@ -43,13 +43,19 @@ const (
TopicScanningStopped = "SCANNING_STOPPED"
TopicScanningCompleted = "SCANNING_COMPLETED"
// QuotaExceedTopic is topic for quota warning event, the usage reaches the warning bar of limitation, like 85%
TopicQuotaWarning = "QUOTA_WARNING"
TopicQuotaExceed = "QUOTA_EXCEED"
TopicReplication = "REPLICATION"
TopicArtifactLabeled = "ARTIFACT_LABELED"
TopicTagRetention = "TAG_RETENTION"
TopicCreateRobot = "CREATE_ROBOT"
TopicDeleteRobot = "DELETE_ROBOT"
TopicQuotaWarning = "QUOTA_WARNING"
TopicQuotaExceed = "QUOTA_EXCEED"
TopicReplication = "REPLICATION"
TopicArtifactLabeled = "ARTIFACT_LABELED"
TopicTagRetention = "TAG_RETENTION"
TopicCreateRobot = "CREATE_ROBOT"
TopicDeleteRobot = "DELETE_ROBOT"
TopicCommonEvent = "COMMON_API"
ResourceTypeProject = "project"
ResourceTypeArtifact = "artifact"
ResourceTypeRepository = "repository"
ResourceTypeRobot = "robot"
ResourceTypeTag = "tag"
)

// CreateProjectEvent is the creating project event
@@ -62,14 +68,16 @@ type CreateProjectEvent struct {
}

// ResolveToAuditLog ...
func (c *CreateProjectEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: c.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: "project",
Resource: c.Project}
func (c *CreateProjectEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: c.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: ResourceTypeProject,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("create project: %s", c.Project),
Resource: c.Project}
return auditLog, nil
}

@@ -88,14 +96,16 @@ type DeleteProjectEvent struct {
}

// ResolveToAuditLog ...
func (d *DeleteProjectEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: d.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: "project",
Resource: d.Project}
func (d *DeleteProjectEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: d.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: ResourceTypeProject,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("delete project: %s", d.Project),
Resource: d.Project}
return auditLog, nil
}

@@ -114,14 +124,16 @@ type DeleteRepositoryEvent struct {
}

// ResolveToAuditLog ...
func (d *DeleteRepositoryEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: d.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: "repository",
Resource: d.Repository,
func (d *DeleteRepositoryEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: d.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: ResourceTypeRepository,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("delete repository: %s", d.Repository),
Resource: d.Repository,
}
return auditLog, nil
}
@@ -154,13 +166,15 @@ type PushArtifactEvent struct {
}

// ResolveToAuditLog ...
func (p *PushArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: p.Artifact.ProjectID,
OpTime: p.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: p.Operator,
ResourceType: "artifact"}
func (p *PushArtifactEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: p.Artifact.ProjectID,
OpTime: p.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: p.Operator,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("push artifact: %s@%s", p.Artifact.RepositoryName, p.Artifact.Digest),
ResourceType: ResourceTypeArtifact}

if len(p.Tags) == 0 {
auditLog.Resource = fmt.Sprintf("%s@%s",
@@ -183,13 +197,15 @@ type PullArtifactEvent struct {
}

// ResolveToAuditLog ...
func (p *PullArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: p.Artifact.ProjectID,
OpTime: p.OccurAt,
Operation: rbac.ActionPull.String(),
Username: p.Operator,
ResourceType: "artifact"}
func (p *PullArtifactEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: p.Artifact.ProjectID,
OpTime: p.OccurAt,
Operation: rbac.ActionPull.String(),
Username: p.Operator,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("pull artifact: %s@%s", p.Artifact.RepositoryName, p.Artifact.Digest),
ResourceType: ResourceTypeArtifact}

if len(p.Tags) == 0 {
auditLog.Resource = fmt.Sprintf("%s@%s",
@@ -219,14 +235,16 @@ type DeleteArtifactEvent struct {
}

// ResolveToAuditLog ...
func (d *DeleteArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: d.Artifact.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: "artifact",
Resource: fmt.Sprintf("%s@%s", d.Artifact.RepositoryName, d.Artifact.Digest)}
func (d *DeleteArtifactEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: d.Artifact.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: ResourceTypeArtifact,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("delete artifact: %s@%s", d.Artifact.RepositoryName, d.Artifact.Digest),
Resource: fmt.Sprintf("%s@%s", d.Artifact.RepositoryName, d.Artifact.Digest)}
return auditLog, nil
}

@@ -246,14 +264,16 @@ type CreateTagEvent struct {
}

// ResolveToAuditLog ...
func (c *CreateTagEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: c.AttachedArtifact.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: "tag",
Resource: fmt.Sprintf("%s:%s", c.Repository, c.Tag)}
func (c *CreateTagEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: c.AttachedArtifact.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: ResourceTypeTag,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("create tag: %s:%s", c.Repository, c.Tag),
Resource: fmt.Sprintf("%s:%s", c.Repository, c.Tag)}
return auditLog, nil
}

@@ -275,13 +295,14 @@ type DeleteTagEvent struct {
}

// ResolveToAuditLog ...
func (d *DeleteTagEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
func (d *DeleteTagEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: d.AttachedArtifact.ProjectID,
OpTime: d.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: d.Operator,
ResourceType: "tag",
ResourceType: ResourceTypeTag,
IsSuccessful: true,
Resource: fmt.Sprintf("%s:%s", d.Repository, d.Tag)}
return auditLog, nil
}
@@ -385,14 +406,16 @@ type CreateRobotEvent struct {
}

// ResolveToAuditLog ...
func (c *CreateRobotEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: c.Robot.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: "robot",
Resource: c.Robot.Name}
func (c *CreateRobotEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: c.Robot.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionCreate.String(),
Username: c.Operator,
ResourceType: ResourceTypeRobot,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("create robot: %s", c.Robot.Name),
Resource: c.Robot.Name}
return auditLog, nil
}

@@ -410,14 +433,16 @@ type DeleteRobotEvent struct {
}

// ResolveToAuditLog ...
func (c *DeleteRobotEvent) ResolveToAuditLog() (*model.AuditLog, error) {
auditLog := &model.AuditLog{
ProjectID: c.Robot.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: c.Operator,
ResourceType: "robot",
Resource: c.Robot.Name}
func (c *DeleteRobotEvent) ResolveToAuditLog() (*model.AuditLogExt, error) {
auditLog := &model.AuditLogExt{
ProjectID: c.Robot.ProjectID,
OpTime: c.OccurAt,
Operation: rbac.ActionDelete.String(),
Username: c.Operator,
ResourceType: ResourceTypeRobot,
IsSuccessful: true,
OperationDescription: fmt.Sprintf("delete robot: %s", c.Robot.Name),
Resource: c.Robot.Name}
return auditLog, nil
}

1 change: 1 addition & 0 deletions src/core/main.go
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ import (
_ "github.com/goharbor/harbor/src/pkg/accessory/model/sbom"
_ "github.com/goharbor/harbor/src/pkg/accessory/model/subject"
"github.com/goharbor/harbor/src/pkg/audit"
_ "github.com/goharbor/harbor/src/pkg/auditext/event/login"
dbCfg "github.com/goharbor/harbor/src/pkg/config/db"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
"github.com/goharbor/harbor/src/pkg/notification"
3 changes: 3 additions & 0 deletions src/lib/config/userconfig.go
Original file line number Diff line number Diff line change
@@ -264,6 +264,9 @@ func BannerMessage(ctx context.Context) string {

// AuditLogEventEnabled returns the audit log enabled setting for a specific event_type, such as delete_user, create_user
func AuditLogEventEnabled(ctx context.Context, eventType string) bool {
if DefaultMgr() == nil || DefaultMgr().Get(ctx, common.AuditLogEventsDisabled) == nil {
return true
}
disableListStr := DefaultMgr().Get(ctx, common.AuditLogEventsDisabled).GetString()
disableList := strings.Split(disableListStr, ",")
for _, t := range disableList {
12 changes: 6 additions & 6 deletions src/pkg/auditext/dao/dao_test.go
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ func (d *daoTestSuite) SetupSuite() {
Resource: "user01",
Username: "admin",
OperationDescription: "Create user",
OperationResult: true,
IsSuccessful: true,
OpTime: time.Now().AddDate(0, 0, -8),
})
d.Require().Nil(err)
@@ -148,11 +148,11 @@ func (d *daoTestSuite) TestListPIDs() {

func (d *daoTestSuite) TestCreate() {
audit := &model.AuditLogExt{
Operation: "create",
ResourceType: "user",
Resource: "user02",
OperationResult: true,
Username: "admin",
Operation: "create",
ResourceType: "user",
Resource: "user02",
IsSuccessful: true,
Username: "admin",
}
_, err := d.dao.Create(d.ctx, audit)
d.Require().Nil(err)
94 changes: 94 additions & 0 deletions src/pkg/auditext/event/login/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package login

import (
"context"
"fmt"
"net/http"
"regexp"
"time"

"github.com/goharbor/harbor/src/common/rbac"
event2 "github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/metadata/commonevent"
"github.com/goharbor/harbor/src/controller/event/model"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/pkg/notifier/event"
)

func init() {
var loginLogoutResolver = &resolver{}
commonevent.RegisterResolver(`/c/login$`, loginLogoutResolver)
commonevent.RegisterResolver(`/c/log_out$`, loginLogoutResolver)
}

const (
opLogout = "logout"
opLogin = "login"
logoutSuffix = "log_out"
payloadPattern = `principal=(.*?)&password`
)

type resolver struct {
}

func (l *resolver) Resolve(ce *commonevent.Metadata, event *event.Event) error {
e := &model.CommonEvent{
Operator: ce.Username,
ResourceType: rbac.ResourceUser.String(),
ResourceName: ce.Username,
OcurrAt: time.Now(),
}

// method POST for login, method GET for logout
if ce.RequestMethod == http.MethodGet {
e.Operation = opLogout
e.OperationDescription = opLogout
} else {
e.Operation = opLogin
e.OperationDescription = opLogin
// Extract the username from payload
re := regexp.MustCompile(payloadPattern)
if len(ce.RequestPayload) > 0 {
match := re.FindStringSubmatch(ce.RequestPayload)
if len(match) > 1 {
e.ResourceName = match[1]
e.Operator = match[1]
}
}
}
e.IsSuccessful = true
if ce.ResponseCode != http.StatusOK {
e.IsSuccessful = false
}
event.Topic = event2.TopicCommonEvent
event.Data = e
return nil
}

func (e *resolver) PreCheck(ctx context.Context, _ string, method string) (bool, string) {
operation := ""
switch method {
case http.MethodPost:
operation = opLogin
case http.MethodGet:
operation = opLogout
}
if len(operation) == 0 {
return false, ""
}
return config.AuditLogEventEnabled(ctx, fmt.Sprintf("%v_%v", operation, rbac.ResourceUser.String())), ""
}
105 changes: 105 additions & 0 deletions src/pkg/auditext/event/login/login_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package login

import (
"context"
"testing"

"github.com/goharbor/harbor/src/controller/event/metadata/commonevent"
"github.com/goharbor/harbor/src/controller/event/model"
"github.com/goharbor/harbor/src/pkg/notifier/event"
)

func Test_resolver_Resolve(t *testing.T) {
type args struct {
ce *commonevent.Metadata
event *event.Event
}
tests := []struct {
name string
l *resolver
args args
wantErr bool
wantUsername string
wantOperation string
wantOperationDescription string
wantIsSuccessful bool
}{

{"test normal", &resolver{}, args{
ce: &commonevent.Metadata{
Username: "test",
RequestURL: "/c/login",
RequestMethod: "POST",
Payload: "principal=test&password=123456",
ResponseCode: 200,
}, event: &event.Event{}}, false, "test", "login", "login", true},
{"test fail", &resolver{}, args{
ce: &commonevent.Metadata{
Username: "test",
RequestURL: "/c/login",
RequestMethod: "POST",
Payload: "principal=test&password=123456",
ResponseCode: 401,
}, event: &event.Event{}}, false, "test", "login", "login", false},
{"test logout", &resolver{}, args{
ce: &commonevent.Metadata{
Username: "test",
RequestURL: "/c/log_out",
RequestMethod: "GET",
Payload: "",
ResponseCode: 200,
}, event: &event.Event{}}, false, "test", "logout", "logout", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := &resolver{}
if err := l.Resolve(tt.args.ce, tt.args.event); (err != nil) != tt.wantErr {
t.Errorf("resolver.Resolve() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.args.event.Data.(*model.CommonEvent).Operator != tt.wantUsername {
t.Errorf("resolver.Resolve() got = %v, want %v", tt.args.event.Data.(*model.CommonEvent).Operator, tt.wantUsername)
}
if tt.args.event.Data.(*model.CommonEvent).Operation != tt.wantOperation {
t.Errorf("resolver.Resolve() got = %v, want %v", tt.args.event.Data.(*model.CommonEvent).Operation, tt.wantOperation)
}
if tt.args.event.Data.(*model.CommonEvent).OperationDescription != tt.wantOperationDescription {
t.Errorf("resolver.Resolve() got = %v, want %v", tt.args.event.Data.(*model.CommonEvent).OperationDescription, tt.wantOperationDescription)
}
if tt.args.event.Data.(*model.CommonEvent).IsSuccessful != tt.wantIsSuccessful {
t.Errorf("resolver.Resolve() got = %v, want %v", tt.args.event.Data.(*model.CommonEvent).IsSuccessful, tt.wantIsSuccessful)
}
})
}
}

func Test_resolver_PreCheck(t *testing.T) {
type args struct {
ctx context.Context
url string
method string
}
tests := []struct {
name string
e *resolver
args args
wantMatched bool
wantResourceName string
}{
{"test normal", &resolver{}, args{context.Background(), "/c/login", "POST"}, true, ""},
{"test fail", &resolver{}, args{context.Background(), "/c/logout", "GET"}, true, ""},
{"test fail method", &resolver{}, args{context.Background(), "/c/login", "PUT"}, false, ""},
{"test fail wrong url", &resolver{}, args{context.Background(), "/c/logout", "DELETE"}, false, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &resolver{}
got, got1 := e.PreCheck(tt.args.ctx, tt.args.url, tt.args.method)
if got != tt.wantMatched {
t.Errorf("resolver.PreCheck() got = %v, want %v", got, tt.wantMatched)
}
if got1 != tt.wantResourceName {
t.Errorf("resolver.PreCheck() got1 = %v, want %v", got1, tt.wantResourceName)
}
})
}
}
2 changes: 1 addition & 1 deletion src/pkg/auditext/model/model.go
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ type AuditLogExt struct {
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
Operation string `orm:"column(operation)" json:"operation"`
OperationDescription string `orm:"column(op_desc)" json:"operation_description"`
OperationResult bool `orm:"column(op_result)" json:"operation_result"`
IsSuccessful bool `orm:"column(op_result)" json:"is_successful"`
ResourceType string `orm:"column(resource_type)" json:"resource_type"`
Resource string `orm:"column(resource)" json:"resource"`
Username string `orm:"column(username)" json:"username"`

0 comments on commit 9cc4519

Please sign in to comment.