Add context to all methods in engine layer
This commit is contained in:
@@ -11,6 +11,7 @@ type sonic struct {
|
|||||||
Port string `default:"4533"`
|
Port string `default:"4533"`
|
||||||
MusicFolder string `default:"./music"`
|
MusicFolder string `default:"./music"`
|
||||||
DbPath string `default:"./data/cloudsonic.db"`
|
DbPath string `default:"./data/cloudsonic.db"`
|
||||||
|
LogLevel string `default:"info"`
|
||||||
|
|
||||||
IgnoredArticles string `default:"The El La Los Las Le Les Os As O A"`
|
IgnoredArticles string `default:"The El La Los Las Le Les Os As O A"`
|
||||||
IndexGroups string `default:"A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ) [Unknown]([)"`
|
IndexGroups string `default:"A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ) [Unknown]([)"`
|
||||||
@@ -21,10 +22,8 @@ type sonic struct {
|
|||||||
PlsIgnoreFolders bool `default:"true"`
|
PlsIgnoreFolders bool `default:"true"`
|
||||||
PlsIgnoredPatterns string `default:"^iCloud;\\~"`
|
PlsIgnoredPatterns string `default:"^iCloud;\\~"`
|
||||||
|
|
||||||
// DevFlags
|
// DevFlags. These are used to enable/disable debugging and incomplete features
|
||||||
LogLevel string `default:"info"`
|
|
||||||
DevDisableAuthentication bool `default:"false"`
|
DevDisableAuthentication bool `default:"false"`
|
||||||
DevDisableFileCheck bool `default:"false"`
|
|
||||||
DevDisableBanner bool `default:"false"`
|
DevDisableBanner bool `default:"false"`
|
||||||
DevInitialPassword string `default:""`
|
DevInitialPassword string `default:""`
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -14,13 +14,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Browser interface {
|
type Browser interface {
|
||||||
MediaFolders() (model.MediaFolders, error)
|
MediaFolders(ctx context.Context) (model.MediaFolders, error)
|
||||||
Indexes(ifModifiedSince time.Time) (model.ArtistIndexes, time.Time, error)
|
Indexes(ctx context.Context, ifModifiedSince time.Time) (model.ArtistIndexes, time.Time, error)
|
||||||
Directory(ctx context.Context, id string) (*DirectoryInfo, error)
|
Directory(ctx context.Context, id string) (*DirectoryInfo, error)
|
||||||
Artist(ctx context.Context, id string) (*DirectoryInfo, error)
|
Artist(ctx context.Context, id string) (*DirectoryInfo, error)
|
||||||
Album(ctx context.Context, id string) (*DirectoryInfo, error)
|
Album(ctx context.Context, id string) (*DirectoryInfo, error)
|
||||||
GetSong(ctx context.Context, id string) (*Entry, error)
|
GetSong(ctx context.Context, id string) (*Entry, error)
|
||||||
GetGenres() (model.Genres, error)
|
GetGenres(ctx context.Context) (model.Genres, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBrowser(ds model.DataStore) Browser {
|
func NewBrowser(ds model.DataStore) Browser {
|
||||||
@@ -31,11 +31,11 @@ type browser struct {
|
|||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *browser) MediaFolders() (model.MediaFolders, error) {
|
func (b *browser) MediaFolders(ctx context.Context) (model.MediaFolders, error) {
|
||||||
return b.ds.MediaFolder().GetAll()
|
return b.ds.MediaFolder().GetAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *browser) Indexes(ifModifiedSince time.Time) (model.ArtistIndexes, time.Time, error) {
|
func (b *browser) Indexes(ctx context.Context, ifModifiedSince time.Time) (model.ArtistIndexes, time.Time, error) {
|
||||||
l, err := b.ds.Property().DefaultGet(model.PropLastScan, "-1")
|
l, err := b.ds.Property().DefaultGet(model.PropLastScan, "-1")
|
||||||
ms, _ := strconv.ParseInt(l, 10, 64)
|
ms, _ := strconv.ParseInt(l, 10, 64)
|
||||||
lastModified := utils.ToTime(ms)
|
lastModified := utils.ToTime(ms)
|
||||||
@@ -136,7 +136,7 @@ func (b *browser) GetSong(ctx context.Context, id string) (*Entry, error) {
|
|||||||
return &entry, nil
|
return &entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *browser) GetGenres() (model.Genres, error) {
|
func (b *browser) GetGenres(ctx context.Context) (model.Genres, error) {
|
||||||
genres, err := b.ds.Genre().GetAll()
|
genres, err := b.ds.Genre().GetAll()
|
||||||
for i, g := range genres {
|
for i, g := range genres {
|
||||||
if strings.TrimSpace(g.Name) == "" {
|
if strings.TrimSpace(g.Name) == "" {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/cloudsonic/sonic-server/model"
|
"github.com/cloudsonic/sonic-server/model"
|
||||||
@@ -24,7 +25,7 @@ var _ = Describe("Browser", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("returns sorted data", func() {
|
It("returns sorted data", func() {
|
||||||
Expect(b.GetGenres()).To(Equal(model.Genres{
|
Expect(b.GetGenres(context.TODO())).To(Equal(model.Genres{
|
||||||
{Name: "<Empty>", SongCount: 13, AlbumCount: 13},
|
{Name: "<Empty>", SongCount: 13, AlbumCount: 13},
|
||||||
{Name: "Electronic", SongCount: 4000, AlbumCount: 40},
|
{Name: "Electronic", SongCount: 4000, AlbumCount: 40},
|
||||||
{Name: "Rock", SongCount: 1000, AlbumCount: 100},
|
{Name: "Rock", SongCount: 1000, AlbumCount: 100},
|
||||||
@@ -33,7 +34,7 @@ var _ = Describe("Browser", func() {
|
|||||||
|
|
||||||
It("bubbles up errors", func() {
|
It("bubbles up errors", func() {
|
||||||
repo.err = errors.New("generic error")
|
repo.err = errors.New("generic error")
|
||||||
_, err := b.GetGenres()
|
_, err := b.GetGenres(context.TODO())
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+3
-2
@@ -2,6 +2,7 @@ package engine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"image"
|
"image"
|
||||||
_ "image/gif"
|
_ "image/gif"
|
||||||
@@ -17,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Cover interface {
|
type Cover interface {
|
||||||
Get(id string, size int, out io.Writer) error
|
Get(ctx context.Context, id string, size int, out io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type cover struct {
|
type cover struct {
|
||||||
@@ -49,7 +50,7 @@ func (c *cover) getCoverPath(id string) (string, error) {
|
|||||||
return "", model.ErrNotFound
|
return "", model.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cover) Get(id string, size int, out io.Writer) error {
|
func (c *cover) Get(ctx context.Context, id string, size int, out io.Writer) error {
|
||||||
path, err := c.getCoverPath(id)
|
path, err := c.getCoverPath(id)
|
||||||
if err != nil && err != model.ErrNotFound {
|
if err != nil && err != model.ErrNotFound {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package engine_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"image"
|
"image"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ func TestCover(t *testing.T) {
|
|||||||
Convey("Subject: GetCoverArt Endpoint", t, func() {
|
Convey("Subject: GetCoverArt Endpoint", t, func() {
|
||||||
Convey("When id is not found", func() {
|
Convey("When id is not found", func() {
|
||||||
mockMediaFileRepo.SetData(`[]`, 1)
|
mockMediaFileRepo.SetData(`[]`, 1)
|
||||||
err := cover.Get("1", 0, out)
|
err := cover.Get(context.TODO(), "1", 0, out)
|
||||||
|
|
||||||
Convey("Then return default cover", func() {
|
Convey("Then return default cover", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@@ -34,7 +35,7 @@ func TestCover(t *testing.T) {
|
|||||||
})
|
})
|
||||||
Convey("When id is found", func() {
|
Convey("When id is found", func() {
|
||||||
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
||||||
err := cover.Get("2", 0, out)
|
err := cover.Get(context.TODO(), "2", 0, out)
|
||||||
|
|
||||||
Convey("Then it should return the cover from the file", func() {
|
Convey("Then it should return the cover from the file", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@@ -44,7 +45,7 @@ func TestCover(t *testing.T) {
|
|||||||
Convey("When there is an error accessing the database", func() {
|
Convey("When there is an error accessing the database", func() {
|
||||||
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
||||||
mockMediaFileRepo.SetError(true)
|
mockMediaFileRepo.SetError(true)
|
||||||
err := cover.Get("2", 0, out)
|
err := cover.Get(context.TODO(), "2", 0, out)
|
||||||
|
|
||||||
Convey("Then error should not be nil", func() {
|
Convey("Then error should not be nil", func() {
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
@@ -52,7 +53,7 @@ func TestCover(t *testing.T) {
|
|||||||
})
|
})
|
||||||
Convey("When id is found but file is not present", func() {
|
Convey("When id is found but file is not present", func() {
|
||||||
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/NOT_FOUND.mp3"}]`, 1)
|
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/NOT_FOUND.mp3"}]`, 1)
|
||||||
err := cover.Get("2", 0, out)
|
err := cover.Get(context.TODO(), "2", 0, out)
|
||||||
|
|
||||||
Convey("Then it should return DatNotFound error", func() {
|
Convey("Then it should return DatNotFound error", func() {
|
||||||
So(err, ShouldEqual, model.ErrNotFound)
|
So(err, ShouldEqual, model.ErrNotFound)
|
||||||
@@ -60,7 +61,7 @@ func TestCover(t *testing.T) {
|
|||||||
})
|
})
|
||||||
Convey("When specifying a size", func() {
|
Convey("When specifying a size", func() {
|
||||||
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
mockMediaFileRepo.SetData(`[{"ID":"2","HasCoverArt":true,"Path":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
||||||
err := cover.Get("2", 100, out)
|
err := cover.Get(context.TODO(), "2", 100, out)
|
||||||
|
|
||||||
Convey("Then image returned should be 100x100", func() {
|
Convey("Then image returned should be 100x100", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@@ -73,7 +74,7 @@ func TestCover(t *testing.T) {
|
|||||||
})
|
})
|
||||||
Convey("When id is for an album", func() {
|
Convey("When id is for an album", func() {
|
||||||
mockAlbumRepo.SetData(`[{"ID":"1","CoverArtPath":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
mockAlbumRepo.SetData(`[{"ID":"1","CoverArtPath":"tests/fixtures/01 Invisible (RED) Edit Version.mp3"}]`, 1)
|
||||||
err := cover.Get("al-1", 0, out)
|
err := cover.Get(context.TODO(), "al-1", 0, out)
|
||||||
|
|
||||||
Convey("Then it should return the cover for the album", func() {
|
Convey("Then it should return the cover for the album", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Playlists interface {
|
type Playlists interface {
|
||||||
GetAll() (model.Playlists, error)
|
GetAll(ctx context.Context) (model.Playlists, error)
|
||||||
Get(ctx context.Context, id string) (*PlaylistInfo, error)
|
Get(ctx context.Context, id string) (*PlaylistInfo, error)
|
||||||
Create(ctx context.Context, playlistId, name string, ids []string) error
|
Create(ctx context.Context, playlistId, name string, ids []string) error
|
||||||
Delete(ctx context.Context, playlistId string) error
|
Delete(ctx context.Context, playlistId string) error
|
||||||
@@ -103,7 +103,7 @@ func (p *playlists) Update(ctx context.Context, playlistId string, name *string,
|
|||||||
return p.ds.Playlist().Put(pls)
|
return p.ds.Playlist().Put(pls)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *playlists) GetAll() (model.Playlists, error) {
|
func (p *playlists) GetAll(ctx context.Context) (model.Playlists, error) {
|
||||||
return p.ds.Playlist().GetAll(model.QueryOptions{})
|
return p.ds.Playlist().GetAll(model.QueryOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -1,6 +1,7 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -11,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Users interface {
|
type Users interface {
|
||||||
Authenticate(username, password, token, salt string) (*model.User, error)
|
Authenticate(ctx context.Context, username, password, token, salt string) (*model.User, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUsers(ds model.DataStore) Users {
|
func NewUsers(ds model.DataStore) Users {
|
||||||
@@ -22,7 +23,7 @@ type users struct {
|
|||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *users) Authenticate(username, pass, token, salt string) (*model.User, error) {
|
func (u *users) Authenticate(ctx context.Context, username, pass, token, salt string) (*model.User, error) {
|
||||||
user, err := u.ds.User().FindByUsername(username)
|
user, err := u.ds.User().FindByUsername(username)
|
||||||
if err == model.ErrNotFound {
|
if err == model.ErrNotFound {
|
||||||
return nil, model.ErrInvalidAuth
|
return nil, model.ErrInvalidAuth
|
||||||
@@ -51,7 +52,7 @@ func (u *users) Authenticate(username, pass, token, salt string) (*model.User, e
|
|||||||
go func() {
|
go func() {
|
||||||
err := u.ds.User().UpdateLastAccessAt(user.ID)
|
err := u.ds.User().UpdateLastAccessAt(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Could not update user's lastAccessAt", "user", user.UserName)
|
log.Error(ctx, "Could not update user's lastAccessAt", "user", user.UserName)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return user, nil
|
return user, nil
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/cloudsonic/sonic-server/model"
|
"github.com/cloudsonic/sonic-server/model"
|
||||||
"github.com/cloudsonic/sonic-server/persistence"
|
"github.com/cloudsonic/sonic-server/persistence"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
@@ -17,20 +19,20 @@ var _ = Describe("Users", func() {
|
|||||||
|
|
||||||
Context("Plaintext password", func() {
|
Context("Plaintext password", func() {
|
||||||
It("authenticates with plaintext password ", func() {
|
It("authenticates with plaintext password ", func() {
|
||||||
usr, err := users.Authenticate("admin", "wordpass", "", "")
|
usr, err := users.Authenticate(context.TODO(), "admin", "wordpass", "", "")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("fails authentication with wrong password", func() {
|
It("fails authentication with wrong password", func() {
|
||||||
_, err := users.Authenticate("admin", "INVALID", "", "")
|
_, err := users.Authenticate(context.TODO(), "admin", "INVALID", "", "")
|
||||||
Expect(err).To(MatchError(model.ErrInvalidAuth))
|
Expect(err).To(MatchError(model.ErrInvalidAuth))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("Encoded password", func() {
|
Context("Encoded password", func() {
|
||||||
It("authenticates with simple encoded password ", func() {
|
It("authenticates with simple encoded password ", func() {
|
||||||
usr, err := users.Authenticate("admin", "enc:776f726470617373", "", "")
|
usr, err := users.Authenticate(context.TODO(), "admin", "enc:776f726470617373", "", "")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
||||||
})
|
})
|
||||||
@@ -38,13 +40,13 @@ var _ = Describe("Users", func() {
|
|||||||
|
|
||||||
Context("Token based authentication", func() {
|
Context("Token based authentication", func() {
|
||||||
It("authenticates with token based authentication", func() {
|
It("authenticates with token based authentication", func() {
|
||||||
usr, err := users.Authenticate("admin", "", "23b342970e25c7928831c3317edd0b67", "retnlmjetrymazgkt")
|
usr, err := users.Authenticate(context.TODO(), "admin", "", "23b342970e25c7928831c3317edd0b67", "retnlmjetrymazgkt")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
Expect(usr).To(Equal(&model.User{UserName: "admin", Password: "wordpass"}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("fails if salt is missing", func() {
|
It("fails if salt is missing", func() {
|
||||||
_, err := users.Authenticate("admin", "", "23b342970e25c7928831c3317edd0b67", "")
|
_, err := users.Authenticate(context.TODO(), "admin", "", "23b342970e25c7928831c3317edd0b67", "")
|
||||||
Expect(err).To(MatchError(model.ErrInvalidAuth))
|
Expect(err).To(MatchError(model.ErrInvalidAuth))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func NewBrowsingController(browser engine.Browser) *BrowsingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *BrowsingController) GetMusicFolders(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *BrowsingController) GetMusicFolders(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
mediaFolderList, _ := c.browser.MediaFolders()
|
mediaFolderList, _ := c.browser.MediaFolders(r.Context())
|
||||||
folders := make([]responses.MusicFolder, len(mediaFolderList))
|
folders := make([]responses.MusicFolder, len(mediaFolderList))
|
||||||
for i, f := range mediaFolderList {
|
for i, f := range mediaFolderList {
|
||||||
folders[i].Id = f.ID
|
folders[i].Id = f.ID
|
||||||
@@ -34,7 +34,7 @@ func (c *BrowsingController) GetMusicFolders(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *BrowsingController) getArtistIndex(r *http.Request, ifModifiedSince time.Time) (*responses.Indexes, error) {
|
func (c *BrowsingController) getArtistIndex(r *http.Request, ifModifiedSince time.Time) (*responses.Indexes, error) {
|
||||||
indexes, lastModified, err := c.browser.Indexes(ifModifiedSince)
|
indexes, lastModified, err := c.browser.Indexes(r.Context(), ifModifiedSince)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, "Error retrieving Indexes", "error", err)
|
log.Error(r, "Error retrieving Indexes", "error", err)
|
||||||
return nil, NewError(responses.ErrorGeneric, "Internal Error")
|
return nil, NewError(responses.ErrorGeneric, "Internal Error")
|
||||||
@@ -152,7 +152,7 @@ func (c *BrowsingController) GetSong(w http.ResponseWriter, r *http.Request) (*r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *BrowsingController) GetGenres(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *BrowsingController) GetGenres(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
genres, err := c.browser.GetGenres()
|
genres, err := c.browser.GetGenres(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, err)
|
log.Error(r, err)
|
||||||
return nil, NewError(responses.ErrorGeneric, "Internal Error")
|
return nil, NewError(responses.ErrorGeneric, "Internal Error")
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func (c *MediaRetrievalController) GetCoverArt(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
size := ParamInt(r, "size", 0)
|
size := ParamInt(r, "size", 0)
|
||||||
|
|
||||||
err = c.cover.Get(id, size, w)
|
err = c.cover.Get(r.Context(), id, size, w)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case err == model.ErrNotFound:
|
case err == model.ErrNotFound:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -17,7 +18,7 @@ type fakeCover struct {
|
|||||||
recvSize int
|
recvSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeCover) Get(id string, size int, out io.Writer) error {
|
func (c *fakeCover) Get(ctx context.Context, id string, size int, out io.Writer) error {
|
||||||
if c.err != nil {
|
if c.err != nil {
|
||||||
return c.err
|
return c.err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func authenticate(users engine.Users) func(next http.Handler) http.Handler {
|
|||||||
token := ParamString(r, "t")
|
token := ParamString(r, "t")
|
||||||
salt := ParamString(r, "s")
|
salt := ParamString(r, "s")
|
||||||
|
|
||||||
usr, err := users.Authenticate(username, pass, token, salt)
|
usr, err := users.Authenticate(r.Context(), username, pass, token, salt)
|
||||||
if err == model.ErrInvalidAuth {
|
if err == model.ErrInvalidAuth {
|
||||||
log.Warn(r, "Invalid login", "username", username, err)
|
log.Warn(r, "Invalid login", "username", username, err)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -113,7 +114,7 @@ type mockUsers struct {
|
|||||||
username, password, token, salt string
|
username, password, token, salt string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockUsers) Authenticate(username, password, token, salt string) (*model.User, error) {
|
func (m *mockUsers) Authenticate(ctx context.Context, username, password, token, salt string) (*model.User, error) {
|
||||||
m.username = username
|
m.username = username
|
||||||
m.password = password
|
m.password = password
|
||||||
m.token = token
|
m.token = token
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func NewPlaylistsController(pls engine.Playlists) *PlaylistsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *PlaylistsController) GetPlaylists(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *PlaylistsController) GetPlaylists(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
allPls, err := c.pls.GetAll()
|
allPls, err := c.pls.GetAll(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, err)
|
log.Error(r, err)
|
||||||
return nil, NewError(responses.ErrorGeneric, "Internal error")
|
return nil, NewError(responses.ErrorGeneric, "Internal error")
|
||||||
|
|||||||
Reference in New Issue
Block a user