chore: keep active users active in scim (#13955)

* chore: scim should keep active users active
* chore: add a unit test to excercise dormancy bug
* audit log should not be dropped when there is no change
* add ability to cancel audit log
This commit is contained in:
Steven Masley
2024-07-19 11:30:02 -10:00
committed by GitHub
parent 49d6d0f41b
commit 03c5d42233
3 changed files with 130 additions and 14 deletions

View File

@ -272,13 +272,14 @@ func (api *API) scimPatchUser(rw http.ResponseWriter, r *http.Request) {
}
auditor := *api.AGPL.Auditor.Load()
aReq, commitAudit := audit.InitRequest[database.User](rw, &audit.RequestParams{
aReq, commitAudit := audit.InitRequestWithCancel[database.User](rw, &audit.RequestParams{
Audit: auditor,
Log: api.Logger,
Request: r,
Action: database.AuditActionWrite,
})
defer commitAudit()
defer commitAudit(true)
id := chi.URLParam(r, "id")
@ -307,23 +308,39 @@ func (api *API) scimPatchUser(rw http.ResponseWriter, r *http.Request) {
var status database.UserStatus
if sUser.Active {
// The user will get transitioned to Active after logging in.
status = database.UserStatusDormant
switch dbUser.Status {
case database.UserStatusActive:
// Keep the user active
status = database.UserStatusActive
case database.UserStatusDormant, database.UserStatusSuspended:
// Move (or keep) as dormant
status = database.UserStatusDormant
default:
// If the status is unknown, just move them to dormant.
// The user will get transitioned to Active after logging in.
status = database.UserStatusDormant
}
} else {
status = database.UserStatusSuspended
}
//nolint:gocritic // needed for SCIM
userNew, err := api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(r.Context()), database.UpdateUserStatusParams{
ID: dbUser.ID,
Status: status,
UpdatedAt: dbtime.Now(),
})
if err != nil {
_ = handlerutil.WriteError(rw, err)
return
if dbUser.Status != status {
//nolint:gocritic // needed for SCIM
userNew, err := api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(r.Context()), database.UpdateUserStatusParams{
ID: dbUser.ID,
Status: status,
UpdatedAt: dbtime.Now(),
})
if err != nil {
_ = handlerutil.WriteError(rw, err)
return
}
dbUser = userNew
} else {
// Do not push an audit log if there is no change.
commitAudit(false)
}
aReq.New = userNew
aReq.New = dbUser
httpapi.Write(ctx, rw, http.StatusOK, sUser)
}