Skip to content

Commit

Permalink
Add OIDC login event
Browse files Browse the repository at this point in the history
Signed-off-by: stonezdj <[email protected]>
  • Loading branch information
stonezdj committed Feb 21, 2025
1 parent 4565907 commit 4a1e0b3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
17 changes: 17 additions & 0 deletions src/core/controllers/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/controller/event/metadata/commonevent"
ctluser "github.com/goharbor/harbor/src/controller/user"
"github.com/goharbor/harbor/src/core/api"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/oidc"
)

Expand All @@ -38,6 +40,8 @@ const userInfoKey = "oidc_user_info"
const redirectURLKey = "oidc_redirect_url"
const oidcUserComment = "Onboarded via OIDC provider"

const loginUserOperation = "login_user"

// OIDCController handles requests for OIDC login, callback and user onboard
type OIDCController struct {
api.BaseController
Expand Down Expand Up @@ -208,6 +212,19 @@ func (oc *OIDCController) Callback() {
redirectURLStr = "/"
}
oc.Controller.Redirect(redirectURLStr, http.StatusFound)
// The log middleware can capture the OIDC user login event with the URL, but it cannot get the current username from security context because the security context is not ready yet.
// need to create login event in the OIDC login call back logic
// to avoid generate duplicate event in audit log ext, the PreCheck function of the login event intentionally bypass the OIDC user login event in log middleware
// and OIDC's login callback function will create the login event and send it to notification.
if config.AuditLogEventEnabled(ctx, loginUserOperation) {
e := &commonevent.Metadata{
Ctx: ctx,
Username: u.Username,
RequestMethod: oc.Ctx.Request.Method,
RequestURL: oc.Ctx.Request.URL.String(),
}
notification.AddEvent(e.Ctx, e, true)
}
}

func userOnboard(ctx context.Context, oc *OIDCController, info *oidc.UserInfo, username string, tokenBytes []byte) (*models.User, bool) {
Expand Down
9 changes: 6 additions & 3 deletions src/pkg/auditext/event/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func init() {
var login = &loginResolver{}
var logout = &logoutResolver{}
commonevent.RegisterResolver(`/c/login$`, login)
commonevent.RegisterResolver(`/c/oidc/callback.*`, login)
commonevent.RegisterResolver(`/c/log_out$`, logout)
}

Expand Down Expand Up @@ -65,9 +66,11 @@ func (l *loginResolver) Resolve(ce *commonevent.Metadata, event *event.Event) er
e.ResourceName = match[1]
e.Operator = match[1]
}
}
if ce.ResponseCode != http.StatusOK {
e.IsSuccessful = false
e.IsSuccessful = ce.ResponseCode == http.StatusOK
} else if ce.RequestMethod == http.MethodGet {
e.IsSuccessful = true // for OIDC login event, always success
e.Operator = ce.Username
e.ResourceName = ce.Username
}
event.Topic = ctlevent.TopicCommonEvent
event.Data = e
Expand Down

0 comments on commit 4a1e0b3

Please sign in to comment.