mirror of
https://github.com/navidrome/navidrome.git
synced 2026-05-03 06:51:16 +00:00
Compare commits
No commits in common. "b1e5ab6fb30ab2fd045c7685917995744775cd0d" and "53641dae88df31e3bf9b1e7381586ac39e8fc26b" have entirely different histories.
b1e5ab6fb3
...
53641dae88
@ -103,7 +103,7 @@ func runList() {
|
||||
options := model.QueryOptions{Sort: "owner_name"}
|
||||
|
||||
if userID != "" {
|
||||
user, err := getUser(ctx, userID, ds)
|
||||
user, err := getUser(userID, ds, ctx)
|
||||
if err != nil {
|
||||
log.Fatal(ctx, "Error retrieving user", "username or id", userID)
|
||||
}
|
||||
|
||||
91
cmd/user.go
91
cmd/user.go
@ -22,6 +22,7 @@ var (
|
||||
email string
|
||||
libraryIds []int
|
||||
name string
|
||||
password string
|
||||
|
||||
removeEmail bool
|
||||
removeName bool
|
||||
@ -35,13 +36,18 @@ func init() {
|
||||
|
||||
userCreateCommand.Flags().StringVarP(&userID, "username", "u", "", "username")
|
||||
|
||||
userCreateCommand.Flags().BoolVar(&setPassword, "set-password", false, "If set, the user's new password will be prompted on the CLI")
|
||||
userCreateCommand.Flags().StringVarP(&password, "password", "p", "", "Set the user's password. Note that this will be captured in terminal history")
|
||||
userCreateCommand.MarkFlagsMutuallyExclusive("password", "set-password")
|
||||
|
||||
userCreateCommand.Flags().StringVarP(&email, "email", "e", "", "New user email")
|
||||
userCreateCommand.Flags().IntSliceVarP(&libraryIds, "library-ids", "i", []int{}, "Comma-separated list of library IDs. Set the user's accessible libraries. If empty, the user can access all libraries. This is incompatible with admin, as admin can always access all libraries")
|
||||
userCreateCommand.Flags().IntSliceVar(&libraryIds, "library-ids", []int{}, "Set the user's accessible libraries. If empty, the user can access all libraries. This is incompatible with admin, as admin can always access all libraries")
|
||||
|
||||
userCreateCommand.Flags().BoolVarP(&setAdmin, "admin", "a", false, "If set, make the user an admin. This user will have access to every library")
|
||||
userCreateCommand.Flags().StringVar(&name, "name", "", "New user's name (this is separate from username used to log in)")
|
||||
|
||||
_ = userCreateCommand.MarkFlagRequired("username")
|
||||
userCreateCommand.MarkFlagsOneRequired("password", "set-password")
|
||||
|
||||
userRoot.AddCommand(userCreateCommand)
|
||||
|
||||
@ -64,8 +70,10 @@ func init() {
|
||||
userEditCommand.MarkFlagsMutuallyExclusive("name", "remove-name")
|
||||
|
||||
userEditCommand.Flags().BoolVar(&setPassword, "set-password", false, "If set, the user's new password will be prompted on the CLI")
|
||||
userEditCommand.Flags().StringVarP(&password, "password", "p", "", "Set the user's password. Note that this will be captured in terminal history")
|
||||
userEditCommand.MarkFlagsMutuallyExclusive("password", "set-password")
|
||||
|
||||
userEditCommand.Flags().IntSliceVarP(&libraryIds, "library-ids", "i", []int{}, "Comma-separated list of library IDs. Set the user's accessible libraries by id")
|
||||
userEditCommand.Flags().IntSliceVar(&libraryIds, "library-ids", []int{}, "Set the user's accessible libraries by id")
|
||||
|
||||
_ = userEditCommand.MarkFlagRequired("user")
|
||||
userRoot.AddCommand(userEditCommand)
|
||||
@ -153,18 +161,12 @@ func promptPassword() string {
|
||||
}
|
||||
}
|
||||
|
||||
func libraryError(libraries model.Libraries) error {
|
||||
ids := make([]int, len(libraries))
|
||||
for idx, library := range libraries {
|
||||
ids[idx] = library.ID
|
||||
}
|
||||
return fmt.Errorf("not all available libraries found. Requested ids: %v, Found libraries: %v", libraryIds, ids)
|
||||
}
|
||||
|
||||
func runCreateUser() {
|
||||
password := promptPassword()
|
||||
if password == "" {
|
||||
log.Fatal("Empty password provided, user creation cancelled")
|
||||
password = promptPassword()
|
||||
if password == "" {
|
||||
log.Fatal("Empty password provided, user creation cancelled")
|
||||
}
|
||||
}
|
||||
|
||||
user := model.User{
|
||||
@ -175,10 +177,6 @@ func runCreateUser() {
|
||||
NewPassword: password,
|
||||
}
|
||||
|
||||
if user.Name == "" {
|
||||
user.Name = userID
|
||||
}
|
||||
|
||||
ds, ctx := getContext()
|
||||
|
||||
err := ds.WithTx(func(tx model.DataStore) error {
|
||||
@ -198,7 +196,7 @@ func runCreateUser() {
|
||||
}
|
||||
|
||||
if len(user.Libraries) != len(libraryIds) {
|
||||
return libraryError(user.Libraries)
|
||||
return fmt.Errorf("not all available libraries found. Requested ids: %v, Found libraries: %d", libraryIds, len(user.Libraries))
|
||||
}
|
||||
} else {
|
||||
user.Libraries, err = tx.Library(ctx).GetAll()
|
||||
@ -212,13 +210,7 @@ func runCreateUser() {
|
||||
return err
|
||||
}
|
||||
|
||||
updatedIds := make([]int, len(user.Libraries))
|
||||
for idx, lib := range user.Libraries {
|
||||
updatedIds[idx] = lib.ID
|
||||
}
|
||||
|
||||
err = tx.User(ctx).SetUserLibraries(user.ID, updatedIds)
|
||||
return err
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@ -244,7 +236,7 @@ func runDeleteUser() {
|
||||
return errors.New("refusing to delete the last user")
|
||||
}
|
||||
|
||||
user, err = getUser(ctx, userID, tx)
|
||||
user, err = getUser(userID, tx, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -267,9 +259,7 @@ func runUserEdit() {
|
||||
changes := []string{}
|
||||
|
||||
err = ds.WithTx(func(tx model.DataStore) error {
|
||||
var newLibraries model.Libraries
|
||||
|
||||
user, err = getUser(ctx, userID, tx)
|
||||
user, err = getUser(userID, tx, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -282,10 +272,10 @@ func runUserEdit() {
|
||||
}
|
||||
|
||||
if len(libraries) != len(libraryIds) {
|
||||
return libraryError(libraries)
|
||||
return fmt.Errorf("not all available libraries found. Requested ids: %v, Found libraries: %d", libraryIds, len(libraries))
|
||||
}
|
||||
|
||||
newLibraries = libraries
|
||||
user.Libraries = libraries
|
||||
changes = append(changes, "updated library ids")
|
||||
}
|
||||
|
||||
@ -298,8 +288,6 @@ func runUserEdit() {
|
||||
user.IsAdmin = true
|
||||
user.Libraries = libraries
|
||||
changes = append(changes, "set admin")
|
||||
|
||||
newLibraries = libraries
|
||||
}
|
||||
|
||||
if setRegularUser && user.IsAdmin {
|
||||
@ -308,12 +296,12 @@ func runUserEdit() {
|
||||
}
|
||||
|
||||
if setPassword {
|
||||
password := promptPassword()
|
||||
password = promptPassword()
|
||||
}
|
||||
|
||||
if password != "" {
|
||||
user.NewPassword = password
|
||||
changes = append(changes, "updated password")
|
||||
}
|
||||
if password != "" {
|
||||
user.NewPassword = password
|
||||
changes = append(changes, "updated password")
|
||||
}
|
||||
|
||||
if email != "" && email != user.Email {
|
||||
@ -333,38 +321,19 @@ func runUserEdit() {
|
||||
}
|
||||
|
||||
if len(changes) == 0 {
|
||||
log.Info(ctx, "No changes for user", "user", user.UserName)
|
||||
return nil
|
||||
}
|
||||
|
||||
err := tx.User(ctx).Put(user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(newLibraries) > 0 {
|
||||
updatedIds := make([]int, len(newLibraries))
|
||||
for idx, lib := range newLibraries {
|
||||
updatedIds[idx] = lib.ID
|
||||
}
|
||||
|
||||
err := tx.User(ctx).SetUserLibraries(user.ID, updatedIds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
err = tx.User(ctx).Put(user)
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(ctx, "Failed to update user", err)
|
||||
}
|
||||
|
||||
if len(changes) == 0 {
|
||||
log.Info(ctx, "No changes for user", "user", user.UserName)
|
||||
} else {
|
||||
log.Info(ctx, "Updated user", "user", user.UserName, "changes", strings.Join(changes, ", "))
|
||||
}
|
||||
log.Info(ctx, "Updated user", "user", user.Name, "changes", strings.Join(changes, ", "))
|
||||
}
|
||||
|
||||
type displayLibrary struct {
|
||||
@ -444,7 +413,7 @@ func runUserList() {
|
||||
user.UpdatedAt.Format(time.RFC3339Nano),
|
||||
lastAccess,
|
||||
lastLogin,
|
||||
fmt.Sprintf("'%s'", strings.Join(paths, "|")),
|
||||
fmt.Sprintf("'%s'", strings.Join(paths, ",")),
|
||||
})
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/navidrome/navidrome/core/auth"
|
||||
"github.com/navidrome/navidrome/db"
|
||||
@ -17,17 +16,17 @@ func getContext() (model.DataStore, context.Context) {
|
||||
return ds, auth.WithAdminUser(context.Background(), ds)
|
||||
}
|
||||
|
||||
func getUser(ctx context.Context, id string, ds model.DataStore) (*model.User, error) {
|
||||
func getUser(id string, ds model.DataStore, ctx context.Context) (*model.User, error) {
|
||||
user, err := ds.User(ctx).FindByUsername(id)
|
||||
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, fmt.Errorf("finding user by name: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
user, err = ds.User(ctx).Get(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("finding user by id: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user