Multiple users, all admins
The single admin account becomes a list of users; config.json moves to version 2 and the old admin is migrated on first start. Every user is an admin. Sessions are tied to a user and their password, so deleting a user or resetting a password signs them out at once. API tokens belong to the user who made them and go away with that user. Admins add users with a temporary password and choose whether it must be changed at first sign-in; until then the API refuses everything but the password change. Settings gets My account and Users cards, and the token table shows each token's owner. 'GHOSTWIRE passwd [username]' resets any user's password. A failed update now also restores config.json, since the new version may have upgraded it.
This commit is contained in:
@@ -43,8 +43,8 @@ Usage (as root):
|
||||
replace the installed binary with this one and restart
|
||||
%s uninstall [-purge] [-y]
|
||||
remove the service, interface and firewall table (-purge also deletes %s)
|
||||
%s passwd
|
||||
set the admin password of the installed service
|
||||
%s passwd [username]
|
||||
set a user's password (default: the first user) of the installed service
|
||||
%s version
|
||||
|
||||
Without a command it runs the service:
|
||||
@@ -433,9 +433,9 @@ func cmdInstall(args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if store.Get().Admin.PasswordHash == "" {
|
||||
fmt.Println("\nChoose the admin password for the web interface (user \"admin\", at least 12 characters).")
|
||||
if err := setPassword(configFile); err != nil {
|
||||
if cfg := store.Get(); !cfg.passwordSet() {
|
||||
fmt.Printf("\nChoose the password for the web interface (user %q, at least 12 characters).\n", cfg.Users[0].Username)
|
||||
if err := setPassword(configFile, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -571,6 +571,11 @@ func cmdUpdate(args []string) error {
|
||||
if rErr := copyFile(oldBin, installBin, 0o755, uid, gid); rErr != nil {
|
||||
return fmt.Errorf("update failed and restoring the old binary failed too: %v (original error: %w)", rErr, err)
|
||||
}
|
||||
// The new version may have upgraded config.json to a format the old
|
||||
// one cannot read.
|
||||
if rErr := copyFile(backup, configFile, 0o600, uid, gid); rErr != nil {
|
||||
return fmt.Errorf("update failed and restoring %s failed too: %v (original error: %w)", configFile, rErr, err)
|
||||
}
|
||||
if rErr := restartAndVerify(); rErr != nil {
|
||||
return fmt.Errorf("update failed and the old version does not start either: %v (original error: %w)", rErr, err)
|
||||
}
|
||||
@@ -649,7 +654,7 @@ func cmdPasswd(args []string) error {
|
||||
if os.Geteuid() != 0 && runtime.GOOS == "linux" {
|
||||
return errors.New("run as root, e.g. with sudo")
|
||||
}
|
||||
if err := setPassword(*path); err != nil {
|
||||
if err := setPassword(*path, fs.Arg(0)); err != nil {
|
||||
return err
|
||||
}
|
||||
if *path == configFile && shOut("systemctl", "is-active", serviceName) == "active" {
|
||||
|
||||
Reference in New Issue
Block a user