package classes import ( "context" "fmt" "time" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/pact" "gorm.io/gorm" ) // Reasons FireAccessRevoked is called with by this plugin. const ( AccessRevokedBan = "ban" AccessRevokedPasswordReset = "password_reset" AccessRevokedPasswordSetByAdmin = "password_set_by_admin" AccessRevokedPasswordChanged = "password_changed" ) // FireAccessRevoked tells the application that userIDs lost every // credential issued before before (reason names why: a ban, a password reset // or change). It fires *AccessRevokedEvent in tx at once, so a listener // error is returned and the caller's transaction rolls back, and then one // "revoked" *pact.MCPSubjectChanged per user once tx commits, so MCP // sessions of those users end on every instance. A nil app or bus, or an // empty id list, does nothing. A nil tx fires the subject events at once. // // The plugin calls it from the ban action, the password reset, an // administrator setting a password and the self-service password change. // RevokeUserAccess, BanUsers and DeactivateUsers do not fire it: an // application that calls RevokeUserAccess or BanUsers directly calls // FireAccessRevoked too, in the same transaction. func FireAccessRevoked(ctx context.Context, app *backpack.App, tx *gorm.DB, userIDs []uint, before time.Time, reason string) error { if app == nil || app.Events == nil || len(userIDs) == 0 { return nil } if ctx == nil { ctx = context.Background() } ids := make([]uint, 0, len(userIDs)) for _, id := range userIDs { if id != 0 { ids = append(ids, id) } } if len(ids) == 0 { return nil } if err := app.Events.Fire(ctx, &AccessRevokedEvent{UserIDs: ids, Before: before, Reason: reason, Tx: tx}); err != nil { return fmt.Errorf("%s: %w", AccessRevokedEventName, err) } for _, id := range ids { FireSubjectChangedAfterCommit(ctx, app, tx, SubjectGuardUser, id, pact.MCPSubjectRevoked) } return nil }