diff --git a/core/playlists/playlists.go b/core/playlists/playlists.go index a0086cd2d..cebb27b77 100644 --- a/core/playlists/playlists.go +++ b/core/playlists/playlists.go @@ -112,7 +112,7 @@ func (s *playlists) Create(ctx context.Context, playlistId string, name string, if err != nil { return err } - if pls.IsSmartPlaylist() { + if pls.IsSmartPlaylist() || pls.IsPluginPlaylist() { return model.ErrNotAuthorized } if !usr.IsAdmin && pls.OwnerID != usr.ID { @@ -218,7 +218,7 @@ func (s *playlists) checkTracksEditable(ctx context.Context, playlistID string) if err != nil { return nil, err } - if pls.IsSmartPlaylist() { + if pls.IsSmartPlaylist() || pls.IsPluginPlaylist() { return nil, model.ErrNotAuthorized } return pls, nil diff --git a/core/playlists/playlists_test.go b/core/playlists/playlists_test.go index 52d5c88d8..12ff44010 100644 --- a/core/playlists/playlists_test.go +++ b/core/playlists/playlists_test.go @@ -80,6 +80,8 @@ var _ = Describe("Playlists", func() { "pls-2": {ID: "pls-2", Name: "Other's", OwnerID: "other-user"}, "pls-smart": {ID: "pls-smart", Name: "Smart", OwnerID: "user-1", Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}}}, + "pls-plugin": {ID: "pls-plugin", Name: "Plugin Playlist", OwnerID: "user-1", + PluginID: "test-plugin", PluginPlaylistID: "daily-mix"}, } ps = playlists.NewPlaylists(ds, core.NewImageUploadService()) }) @@ -125,6 +127,12 @@ var _ = Describe("Playlists", func() { _, err := ps.Create(ctx, "pls-smart", "", []string{"song-1"}) Expect(err).To(MatchError(model.ErrNotAuthorized)) }) + + It("denies replacing tracks on a plugin playlist", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + _, err := ps.Create(ctx, "pls-plugin", "", []string{"song-1"}) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) }) Describe("Update", func() { @@ -137,6 +145,8 @@ var _ = Describe("Playlists", func() { "pls-other": {ID: "pls-other", Name: "Other's", OwnerID: "other-user"}, "pls-smart": {ID: "pls-smart", Name: "Smart", OwnerID: "user-1", Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}}}, + "pls-plugin": {ID: "pls-plugin", Name: "Plugin Playlist", OwnerID: "user-1", + PluginID: "test-plugin", PluginPlaylistID: "daily-mix"}, } mockPlsRepo.TracksRepo = mockTracks ps = playlists.NewPlaylists(ds, core.NewImageUploadService()) @@ -182,6 +192,18 @@ var _ = Describe("Playlists", func() { Expect(err).To(MatchError(model.ErrNotAuthorized)) }) + It("denies adding tracks to a plugin playlist", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + err := ps.Update(ctx, "pls-plugin", nil, nil, nil, []string{"song-1"}, nil) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) + + It("denies removing tracks from a plugin playlist", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + err := ps.Update(ctx, "pls-plugin", nil, nil, nil, nil, []int{0}) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) + It("allows metadata updates on a smart playlist", func() { ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) newName := "Updated Smart" @@ -199,6 +221,8 @@ var _ = Describe("Playlists", func() { "pls-1": {ID: "pls-1", Name: "My Playlist", OwnerID: "user-1"}, "pls-smart": {ID: "pls-smart", Name: "Smart", OwnerID: "user-1", Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}}}, + "pls-plugin": {ID: "pls-plugin", Name: "Plugin Playlist", OwnerID: "user-1", + PluginID: "test-plugin", PluginPlaylistID: "daily-mix"}, "pls-other": {ID: "pls-other", Name: "Other's", OwnerID: "other-user"}, } mockPlsRepo.TracksRepo = mockTracks @@ -232,6 +256,12 @@ var _ = Describe("Playlists", func() { Expect(err).To(MatchError(model.ErrNotAuthorized)) }) + It("denies editing plugin playlists", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + _, err := ps.AddTracks(ctx, "pls-plugin", []string{"song-1"}) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) + It("returns error when playlist not found", func() { ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) _, err := ps.AddTracks(ctx, "nonexistent", []string{"song-1"}) @@ -248,6 +278,8 @@ var _ = Describe("Playlists", func() { "pls-1": {ID: "pls-1", Name: "My Playlist", OwnerID: "user-1"}, "pls-smart": {ID: "pls-smart", Name: "Smart", OwnerID: "user-1", Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}}}, + "pls-plugin": {ID: "pls-plugin", Name: "Plugin Playlist", OwnerID: "user-1", + PluginID: "test-plugin", PluginPlaylistID: "daily-mix"}, } mockPlsRepo.TracksRepo = mockTracks ps = playlists.NewPlaylists(ds, core.NewImageUploadService()) @@ -266,6 +298,12 @@ var _ = Describe("Playlists", func() { Expect(err).To(MatchError(model.ErrNotAuthorized)) }) + It("denies on plugin playlist", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + err := ps.RemoveTracks(ctx, "pls-plugin", []string{"track-1"}) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) + It("denies non-owner", func() { ctx = request.WithUser(ctx, model.User{ID: "other-user", IsAdmin: false}) err := ps.RemoveTracks(ctx, "pls-1", []string{"track-1"}) @@ -282,6 +320,8 @@ var _ = Describe("Playlists", func() { "pls-1": {ID: "pls-1", Name: "My Playlist", OwnerID: "user-1"}, "pls-smart": {ID: "pls-smart", Name: "Smart", OwnerID: "user-1", Rules: &criteria.Criteria{Expression: criteria.Contains{"title": "test"}}}, + "pls-plugin": {ID: "pls-plugin", Name: "Plugin Playlist", OwnerID: "user-1", + PluginID: "test-plugin", PluginPlaylistID: "daily-mix"}, } mockPlsRepo.TracksRepo = mockTracks ps = playlists.NewPlaylists(ds, core.NewImageUploadService()) @@ -299,6 +339,12 @@ var _ = Describe("Playlists", func() { err := ps.ReorderTrack(ctx, "pls-smart", 1, 3) Expect(err).To(MatchError(model.ErrNotAuthorized)) }) + + It("denies on plugin playlist", func() { + ctx = request.WithUser(ctx, model.User{ID: "user-1", IsAdmin: false}) + err := ps.ReorderTrack(ctx, "pls-plugin", 1, 3) + Expect(err).To(MatchError(model.ErrNotAuthorized)) + }) }) Describe("SetImage", func() {