feat: password-change hook and the reset-2FA admin slot
The D-07 password-change hook is the existing AccessRevokedEvent, fired inside the write's transaction by a reset, the user's own change and an administrator's password; (*AccessRevokedEvent).PasswordChanged reports those three reasons, and the login rehash fires nothing. The Users screen declares the record action reset_two_factor (danger) behind the new permission golem15.users.reset_two_factor, which no role has by default. It is offered only when a two-factor plugin publishes a classes.TwoFactorAdmin and the user has a second factor; Run calls the service's Reset in the action's transaction.
This commit is contained in:
38
classes/two_factor_admin.go
Normal file
38
classes/two_factor_admin.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package classes
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.golem15.com/golem15/sm-user-plugin/models"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// PermissionResetTwoFactor is the backend permission an administrator needs
|
||||
// to run the Users screen's "Reset 2FA" record action (reset_two_factor). No
|
||||
// role has it by default: only a superuser, or a role granted it
|
||||
// explicitly, may remove a user's second factors.
|
||||
const PermissionResetTwoFactor = "golem15.users.reset_two_factor"
|
||||
|
||||
// TwoFactorAdmin is what a two-factor plugin publishes so the Users screen
|
||||
// can offer its "Reset 2FA" record action. The screen looks it up on every
|
||||
// request: without a published service the action is never offered, so an
|
||||
// application that mounts no two-factor plugin never shows it.
|
||||
//
|
||||
// Publish it with an explicit type argument,
|
||||
//
|
||||
// app.Publish[classes.TwoFactorAdmin](svc)
|
||||
//
|
||||
// because a bare app.Publish(svc) keys the service on its concrete type and
|
||||
// the lookup misses it.
|
||||
type TwoFactorAdmin interface {
|
||||
// HasTwoFactor reports whether the user has any second factor (an
|
||||
// enabled method, a WebAuthn credential, recovery codes or a trusted
|
||||
// device) to reset. It only reads, through tx.
|
||||
HasTwoFactor(ctx context.Context, tx *gorm.DB, userID uint) (bool, error)
|
||||
// Reset disables every second-factor method of user, deletes the
|
||||
// WebAuthn credentials and recovery codes, revokes the trusted devices
|
||||
// and fires the plugin's disabled event, all on tx (the record action's
|
||||
// transaction): an error rolls the reset back. The user then signs in
|
||||
// with the password alone until they set up a second factor again.
|
||||
Reset(ctx context.Context, tx *gorm.DB, user *models.User) error
|
||||
}
|
||||
Reference in New Issue
Block a user