Password: fail loudly when settings cannot be saved (#30767)
This commit is contained in:
parent
cb09fccd34
commit
c92fb3a4f1
4 changed files with 34 additions and 3 deletions
|
|
@ -1,6 +1,10 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/evcc-io/evcc/server/db"
|
||||||
|
"github.com/evcc-io/evcc/server/db/settings"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -12,3 +16,19 @@ var passwordCmd = &cobra.Command{
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(passwordCmd)
|
rootCmd.AddCommand(passwordCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fatalDatabase logs a database error and exits, hinting at file permissions
|
||||||
|
// when the database is not writable by the current user.
|
||||||
|
func fatalDatabase(err error) {
|
||||||
|
if db.IsReadonly(err) {
|
||||||
|
log.FATAL.Println("database is not writable; run this command as the user owning the database file, e.g. sudo -u evcc")
|
||||||
|
}
|
||||||
|
log.FATAL.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// persistPasswordSettings writes pending settings to the database
|
||||||
|
func persistPasswordSettings() {
|
||||||
|
if err := settings.Persist(); err != nil {
|
||||||
|
fatalDatabase(fmt.Errorf("cannot save settings: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func runPasswordReset(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
// setup persistence
|
// setup persistence
|
||||||
if err := configureDatabase(conf.Database); err != nil {
|
if err := configureDatabase(conf.Database); err != nil {
|
||||||
log.FATAL.Fatal(err)
|
fatalDatabase(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
confirm, _ := cmd.Flags().GetBool(flagForce)
|
confirm, _ := cmd.Flags().GetBool(flagForce)
|
||||||
|
|
@ -44,5 +44,6 @@ func runPasswordReset(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
if confirm {
|
if confirm {
|
||||||
auth.New().RemoveAdminPassword()
|
auth.New().RemoveAdminPassword()
|
||||||
|
persistPasswordSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func runPasswordSet(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
// setup persistence
|
// setup persistence
|
||||||
if err := configureDatabase(conf.Database); err != nil {
|
if err := configureDatabase(conf.Database); err != nil {
|
||||||
log.FATAL.Fatal(err)
|
fatalDatabase(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt := &survey.Password{
|
prompt := &survey.Password{
|
||||||
|
|
@ -40,7 +40,9 @@ func runPasswordSet(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
if password == "" {
|
if password == "" {
|
||||||
log.FATAL.Fatal("password cannot be empty")
|
log.FATAL.Fatal("password cannot be empty")
|
||||||
|
} else if err := auth.New().SetAdminPassword(password); err != nil {
|
||||||
|
log.FATAL.Fatal(err)
|
||||||
} else {
|
} else {
|
||||||
auth.New().SetAdminPassword(password)
|
persistPasswordSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
sqlite3 "modernc.org/sqlite"
|
sqlite3 "modernc.org/sqlite"
|
||||||
|
sqlite3lib "modernc.org/sqlite/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -112,6 +113,13 @@ func Close() error {
|
||||||
return db.Close()
|
return db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsReadonly reports whether err indicates a database file that is not
|
||||||
|
// writable by the current user. The code mask covers extended result codes.
|
||||||
|
func IsReadonly(err error) bool {
|
||||||
|
var serr *sqlite3.Error
|
||||||
|
return errors.As(err, &serr) && serr.Code()&0xff == sqlite3lib.SQLITE_READONLY
|
||||||
|
}
|
||||||
|
|
||||||
type backuper interface {
|
type backuper interface {
|
||||||
NewBackup(string) (*sqlite3.Backup, error)
|
NewBackup(string) (*sqlite3.Backup, error)
|
||||||
NewRestore(string) (*sqlite3.Backup, error)
|
NewRestore(string) (*sqlite3.Backup, error)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue