Adding upstream version 0.28.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
88f1d47ab6
commit
e28c88ef14
933 changed files with 194711 additions and 0 deletions
118
core/record_model_superusers.go
Normal file
118
core/record_model_superusers.go
Normal file
|
@ -0,0 +1,118 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/hook"
|
||||
"github.com/pocketbase/pocketbase/tools/router"
|
||||
)
|
||||
|
||||
const CollectionNameSuperusers = "_superusers"
|
||||
|
||||
// DefaultInstallerEmail is the default superuser email address
|
||||
// for the initial autogenerated superuser account.
|
||||
const DefaultInstallerEmail = "__pbinstaller@example.com"
|
||||
|
||||
func (app *BaseApp) registerSuperuserHooks() {
|
||||
app.OnRecordDelete(CollectionNameSuperusers).Bind(&hook.Handler[*RecordEvent]{
|
||||
Id: "pbSuperusersRecordDelete",
|
||||
Func: func(e *RecordEvent) error {
|
||||
originalApp := e.App
|
||||
txErr := e.App.RunInTransaction(func(txApp App) error {
|
||||
e.App = txApp
|
||||
|
||||
total, err := e.App.CountRecords(CollectionNameSuperusers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch total superusers count: %w", err)
|
||||
}
|
||||
|
||||
if total == 1 {
|
||||
return router.NewBadRequestError("You can't delete the only existing superuser", nil)
|
||||
}
|
||||
|
||||
return e.Next()
|
||||
})
|
||||
e.App = originalApp
|
||||
|
||||
return txErr
|
||||
},
|
||||
Priority: -99,
|
||||
})
|
||||
|
||||
recordSaveHandler := &hook.Handler[*RecordEvent]{
|
||||
Id: "pbSuperusersRecordSaveExec",
|
||||
Func: func(e *RecordEvent) error {
|
||||
e.Record.SetVerified(true) // always mark superusers as verified
|
||||
|
||||
if err := e.Next(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ensure that the installer superuser is deleted
|
||||
if e.Type == ModelEventTypeCreate && e.Record.Email() != DefaultInstallerEmail {
|
||||
record, err := app.FindAuthRecordByEmail(CollectionNameSuperusers, DefaultInstallerEmail)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
// already deleted
|
||||
} else if err != nil {
|
||||
e.App.Logger().Warn("Failed to fetch installer superuser", "error", err)
|
||||
} else {
|
||||
err = e.App.Delete(record)
|
||||
if err != nil {
|
||||
e.App.Logger().Warn("Failed to delete installer superuser", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Priority: -99,
|
||||
}
|
||||
app.OnRecordCreateExecute(CollectionNameSuperusers).Bind(recordSaveHandler)
|
||||
app.OnRecordUpdateExecute(CollectionNameSuperusers).Bind(recordSaveHandler)
|
||||
|
||||
// prevent sending password reset emails to the installer address
|
||||
app.OnMailerRecordPasswordResetSend(CollectionNameSuperusers).Bind(&hook.Handler[*MailerRecordEvent]{
|
||||
Id: "pbSuperusersInstallerPasswordReset",
|
||||
Func: func(e *MailerRecordEvent) error {
|
||||
if e.Record.Email() == DefaultInstallerEmail {
|
||||
return errors.New("cannot reset the password for the installer superuser")
|
||||
}
|
||||
|
||||
return e.Next()
|
||||
},
|
||||
})
|
||||
|
||||
collectionSaveHandler := &hook.Handler[*CollectionEvent]{
|
||||
Id: "pbSuperusersCollectionSaveExec",
|
||||
Func: func(e *CollectionEvent) error {
|
||||
// don't allow name change even if executed with SaveNoValidate
|
||||
e.Collection.Name = CollectionNameSuperusers
|
||||
|
||||
// for now don't allow superusers OAuth2 since we don't want
|
||||
// to accidentally create a new superuser by just OAuth2 signin
|
||||
e.Collection.OAuth2.Enabled = false
|
||||
e.Collection.OAuth2.Providers = nil
|
||||
|
||||
// force password auth
|
||||
e.Collection.PasswordAuth.Enabled = true
|
||||
|
||||
// for superusers we don't allow for now standalone OTP auth and always require to be combined with MFA
|
||||
if e.Collection.OTP.Enabled {
|
||||
e.Collection.MFA.Enabled = true
|
||||
}
|
||||
|
||||
return e.Next()
|
||||
},
|
||||
Priority: 99,
|
||||
}
|
||||
app.OnCollectionCreateExecute(CollectionNameSuperusers).Bind(collectionSaveHandler)
|
||||
app.OnCollectionUpdateExecute(CollectionNameSuperusers).Bind(collectionSaveHandler)
|
||||
}
|
||||
|
||||
// IsSuperuser returns whether the current record is a superuser, aka.
|
||||
// whether the record is from the _superusers collection.
|
||||
func (m *Record) IsSuperuser() bool {
|
||||
return m.Collection().Name == CollectionNameSuperusers
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue