Skip to content

Commit

Permalink
Add OIDC login event (goharbor#21650)
Browse files Browse the repository at this point in the history
Signed-off-by: stonezdj <[email protected]>
  • Loading branch information
stonezdj authored Feb 21, 2025
1 parent b837bbb commit e5e1318
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 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
10 changes: 6 additions & 4 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 All @@ -54,7 +55,7 @@ func (l *loginResolver) Resolve(ce *commonevent.Metadata, event *event.Event) er
OcurrAt: time.Now(),
Operation: opLogin,
OperationDescription: opLogin,
IsSuccessful: true,
IsSuccessful: ce.ResponseCode <= http.StatusTemporaryRedirect,
}

// Extract the username from payload
Expand All @@ -65,9 +66,10 @@ 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
} 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 e5e1318

Please sign in to comment.