mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-10 19:37:08 +02:00
40 lines
1.1 KiB
Go
40 lines
1.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/navidrome/navidrome/log"
|
|
"github.com/navidrome/navidrome/model"
|
|
"github.com/navidrome/navidrome/model/id"
|
|
"golang.org/x/text/cases"
|
|
"golang.org/x/text/language"
|
|
)
|
|
|
|
var ErrSetupComplete = errors.New("setup already complete")
|
|
|
|
// CreateFirstAdmin must run inside ds.WithTxImmediate, so the count and the insert cannot interleave.
|
|
func CreateFirstAdmin(ctx context.Context, tx model.DataStore, username, password string) (*model.User, error) {
|
|
count, err := tx.User().CountAll(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("counting users: %w", err)
|
|
}
|
|
if count > 0 {
|
|
return nil, ErrSetupComplete
|
|
}
|
|
log.Warn(ctx, "Creating initial user", "user", username)
|
|
u := model.User{
|
|
ID: id.NewRandom(),
|
|
UserName: username,
|
|
Name: cases.Title(language.Und).String(username),
|
|
NewPassword: password,
|
|
IsAdmin: true,
|
|
LastLoginAt: new(time.Now()),
|
|
}
|
|
if err := tx.User().Put(ctx, &u); err != nil {
|
|
return nil, fmt.Errorf("creating initial user: %w", err)
|
|
}
|
|
return tx.User().Get(ctx, u.ID)
|
|
}
|