navidrome/core/players.go
Kendall Garner fa85e2a781
Use userId in player, other fixes (#3182)
* [bugfix] player: use userId, other fixes

This PR primarily resolves #1928 by switching the foreign key of `player` from `user.user_name` to `user.id`.
There are also a few other fixes/changes:

- For some bizarre reason, `ip_address` is never returned from `read`/`get`. Change the field to `ip`, which works. Somehow
- Update `players_test.go` mock to also check for user agent, replicating the actual code
- Update `player_repository.go` `isPermitted` to check user id. I don't know how this worked before...
- tests!
- a few places referred to `typ`, when it is really `userAgent`. Change the field names

* baseRequest -> selectPlayer

* remove comment

* update migration, make all of persistence foreign key enabled

* maybe don't forget to save the file first
2024-08-03 13:37:21 -04:00

69 lines
1.8 KiB
Go

package core
import (
"context"
"fmt"
"time"
"github.com/google/uuid"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/request"
)
type Players interface {
Get(ctx context.Context, playerId string) (*model.Player, error)
Register(ctx context.Context, id, client, userAgent, ip string) (*model.Player, *model.Transcoding, error)
}
func NewPlayers(ds model.DataStore) Players {
return &players{ds}
}
type players struct {
ds model.DataStore
}
func (p *players) Register(ctx context.Context, id, client, userAgent, ip string) (*model.Player, *model.Transcoding, error) {
var plr *model.Player
var trc *model.Transcoding
var err error
user, _ := request.UserFrom(ctx)
if id != "" {
plr, err = p.ds.Player(ctx).Get(id)
if err == nil && plr.Client != client {
id = ""
}
}
if err != nil || id == "" {
plr, err = p.ds.Player(ctx).FindMatch(user.ID, client, userAgent)
if err == nil {
log.Debug(ctx, "Found matching player", "id", plr.ID, "client", client, "username", userName, "type", userAgent)
} else {
plr = &model.Player{
ID: uuid.NewString(),
UserId: user.ID,
Client: client,
ScrobbleEnabled: true,
}
log.Info(ctx, "Registering new player", "id", plr.ID, "client", client, "username", userName, "type", userAgent)
}
}
plr.Name = fmt.Sprintf("%s [%s]", client, userAgent)
plr.UserAgent = userAgent
plr.IP = ip
plr.LastSeen = time.Now()
err = p.ds.Player(ctx).Put(plr)
if err != nil {
return nil, nil, err
}
if plr.TranscodingId != "" {
trc, err = p.ds.Transcoding(ctx).Get(plr.TranscodingId)
}
return plr, trc, err
}
func (p *players) Get(ctx context.Context, playerId string) (*model.Player, error) {
return p.ds.Player(ctx).Get(playerId)
}