From 7fe15134a60b318f99a0aaa9dabc1ecc53417163 Mon Sep 17 00:00:00 2001 From: Deluan Date: Tue, 21 Jan 2020 17:18:46 -0500 Subject: [PATCH] Check permissions to playlist operations --- engine/playlists.go | 33 ++++++++++++++++++++++++----- model/datastore.go | 7 ------ model/errors.go | 9 ++++++++ server/subsonic/playlists.go | 6 ++++++ server/subsonic/responses/errors.go | 16 +++++++------- 5 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 model/errors.go diff --git a/engine/playlists.go b/engine/playlists.go index a2c5e5b72..88c749d26 100644 --- a/engine/playlists.go +++ b/engine/playlists.go @@ -25,11 +25,7 @@ type playlists struct { } func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []string) error { - owner := consts.InitialUserName - user, ok := ctx.Value("user").(*model.User) - if ok { - owner = user.UserName - } + owner := p.getUser(ctx) var pls *model.Playlist var err error // If playlistID is present, override tracks @@ -38,6 +34,9 @@ func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []s if err != nil { return err } + if owner != pls.Owner { + return model.ErrNotAuthorized + } pls.Tracks = nil } else { pls = &model.Playlist{ @@ -52,12 +51,36 @@ func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []s return p.ds.Playlist().Put(pls) } +func (p *playlists) getUser(ctx context.Context) string { + owner := consts.InitialUserName + user, ok := ctx.Value("user").(*model.User) + if ok { + owner = user.UserName + } + return owner +} + func (p *playlists) Delete(ctx context.Context, playlistId string) error { + pls, err := p.ds.Playlist().Get(playlistId) + if err != nil { + return err + } + + owner := p.getUser(ctx) + if owner != pls.Owner { + return model.ErrNotAuthorized + } return p.ds.Playlist().Delete(playlistId) } func (p *playlists) Update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error { pls, err := p.ds.Playlist().Get(playlistId) + + owner := p.getUser(ctx) + if owner != pls.Owner { + return model.ErrNotAuthorized + } + if err != nil { return err } diff --git a/model/datastore.go b/model/datastore.go index aa6570571..a6d8ba0cc 100644 --- a/model/datastore.go +++ b/model/datastore.go @@ -1,16 +1,9 @@ package model import ( - "errors" - "github.com/deluan/rest" ) -var ( - ErrNotFound = errors.New("data not found") - ErrInvalidAuth = errors.New("invalid authentication") -) - // Filters use the same operators as Beego ORM: See https://beego.me/docs/mvc/model/query.md#operators // Ex: var q = QueryOptions{Filters: Filters{"name__istartswith": "Deluan","age__gt": 25}} // All conditions will be ANDed together diff --git a/model/errors.go b/model/errors.go new file mode 100644 index 000000000..c9c1bea55 --- /dev/null +++ b/model/errors.go @@ -0,0 +1,9 @@ +package model + +import "errors" + +var ( + ErrNotFound = errors.New("data not found") + ErrInvalidAuth = errors.New("invalid authentication") + ErrNotAuthorized = errors.New("not authorized") +) diff --git a/server/subsonic/playlists.go b/server/subsonic/playlists.go index 5cb6aa1d8..f4f82bf39 100644 --- a/server/subsonic/playlists.go +++ b/server/subsonic/playlists.go @@ -81,6 +81,9 @@ func (c *PlaylistsController) DeletePlaylist(w http.ResponseWriter, r *http.Requ return nil, err } err = c.pls.Delete(r.Context(), id) + if err == model.ErrNotAuthorized { + return nil, NewError(responses.ErrorAuthorizationFail) + } if err != nil { log.Error(r, err) return nil, NewError(responses.ErrorGeneric, "Internal Error") @@ -110,6 +113,9 @@ func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Requ log.Debug(r, fmt.Sprintf("-- Removing: '%v'", songIndexesToRemove)) err = c.pls.Update(r.Context(), playlistId, pname, songsToAdd, songIndexesToRemove) + if err == model.ErrNotAuthorized { + return nil, NewError(responses.ErrorAuthorizationFail) + } if err != nil { log.Error(r, err) return nil, NewError(responses.ErrorGeneric, "Internal Error") diff --git a/server/subsonic/responses/errors.go b/server/subsonic/responses/errors.go index 343d49370..c15ccd92c 100644 --- a/server/subsonic/responses/errors.go +++ b/server/subsonic/responses/errors.go @@ -1,14 +1,14 @@ package responses const ( - ErrorGeneric = iota * 10 - ErrorMissingParameter - ErrorClientTooOld - ErrorServerTooOld - ErrorAuthenticationFail - ErrorAuthorizationFail - ErrorTrialExpired - ErrorDataNotFound + ErrorGeneric = 0 + ErrorMissingParameter = 10 + ErrorClientTooOld = 20 + ErrorServerTooOld = 30 + ErrorAuthenticationFail = 40 + ErrorAuthorizationFail = 50 + ErrorTrialExpired = 60 + ErrorDataNotFound = 70 ) var errors = map[int]string{