fix(events): build event doers without re-fetching the user

GetUserOrLinkShareUser re-fetches the account and fails its status
check, which broke deleting a disabled user's projects (the deletion
runs with the disabled account as doer). Convert the authenticated
principal directly instead — it also matches what the events serialized
before the doer became concrete, and drops a query per event.
This commit is contained in:
kolaente 2026-06-12 09:36:07 +02:00 committed by kolaente
parent b3bcab1f72
commit f0eff52949
5 changed files with 19 additions and 25 deletions

View File

@ -1217,13 +1217,9 @@ func UpdateProject(s *xorm.Session, project *Project, auth web.Auth, updateProje
return err
}
doer, err := GetUserOrLinkShareUser(s, auth)
if err != nil {
return err
}
events.DispatchOnCommit(s, &ProjectUpdatedEvent{
Project: project,
Doer: doer,
Doer: doerFromAuth(auth),
})
l, err := GetProjectSimpleByID(s, project.ID)
@ -1452,13 +1448,9 @@ func (p *Project) Delete(s *xorm.Session, a web.Auth) (err error) {
return
}
doer, err := GetUserOrLinkShareUser(s, a)
if err != nil {
return err
}
events.DispatchOnCommit(s, &ProjectDeletedEvent{
Project: fullProject,
Doer: doer,
Doer: doerFromAuth(a),
})
childProjects := []*Project{}

View File

@ -109,14 +109,10 @@ func (tl *TeamProject) Create(s *xorm.Session, a web.Auth) (err error) {
return err
}
doer, err := GetUserOrLinkShareUser(s, a)
if err != nil {
return err
}
events.DispatchOnCommit(s, &ProjectSharedWithTeamEvent{
Project: l,
Team: team,
Doer: doer,
Doer: doerFromAuth(a),
})
err = updateProjectLastUpdated(s, l)

View File

@ -115,14 +115,10 @@ func (lu *ProjectUser) Create(s *xorm.Session, a web.Auth) (err error) {
return err
}
doer, err := GetUserOrLinkShareUser(s, a)
if err != nil {
return err
}
events.DispatchOnCommit(s, &ProjectSharedWithUserEvent{
Project: l,
User: u,
Doer: doer,
Doer: doerFromAuth(a),
})
err = updateProjectLastUpdated(s, l)

View File

@ -360,13 +360,9 @@ func (t *Team) Delete(s *xorm.Session, a web.Auth) (err error) {
return
}
doer, err := GetUserOrLinkShareUser(s, a)
if err != nil {
return err
}
events.DispatchOnCommit(s, &TeamDeletedEvent{
Team: t,
Doer: doer,
Doer: doerFromAuth(a),
})
return nil
}

View File

@ -22,6 +22,20 @@ import (
"xorm.io/xorm"
)
// doerFromAuth converts the authenticated principal into a user for event
// payloads without re-fetching it. A re-fetch would fail its status check in
// flows acting on behalf of disabled accounts (e.g. user deletion), and the
// event only needs the principal as it authenticated.
func doerFromAuth(a web.Auth) *user.User {
if u, is := a.(*user.User); is {
return u
}
if share, is := a.(*LinkSharing); is {
return share.toUser()
}
return &user.User{ID: a.GetID()}
}
// GetUserOrLinkShareUser returns either a user or a link share disguised as a user.
func GetUserOrLinkShareUser(s *xorm.Session, a web.Auth) (uu *user.User, err error) {
if u, is := a.(*user.User); is {