diff --git a/app/Commands/EditTrackCommand.php b/app/Commands/EditTrackCommand.php index b7329ef0..c9688344 100644 --- a/app/Commands/EditTrackCommand.php +++ b/app/Commands/EditTrackCommand.php @@ -20,6 +20,7 @@ namespace Poniverse\Ponyfm\Commands; +use Gate; use Poniverse\Ponyfm\Models\Album; use Poniverse\Ponyfm\Models\Image; use Poniverse\Ponyfm\Models\Track; @@ -46,9 +47,7 @@ class EditTrackCommand extends CommandBase */ public function authorize() { - $user = \Auth::user(); - - return $this->_track && $user != null && $this->_track->user_id == $user->id; + return $this->_track && Gate::allows('edit', $this->_track); } /** diff --git a/app/Http/Controllers/Api/Web/AlbumsController.php b/app/Http/Controllers/Api/Web/AlbumsController.php index a494d28c..c6b718f9 100644 --- a/app/Http/Controllers/Api/Web/AlbumsController.php +++ b/app/Http/Controllers/Api/Web/AlbumsController.php @@ -30,6 +30,7 @@ use Poniverse\Ponyfm\Models\Image; use Poniverse\Ponyfm\Models\ResourceLogItem; use Auth; use Input; +use Poniverse\Ponyfm\Models\User; use Response; use Poniverse\Ponyfm\Models\Track; @@ -140,9 +141,12 @@ class AlbumsController extends ApiControllerBase 200); } - public function getOwned() + public function getOwned($id) { - $query = Album::summary()->where('user_id', \Auth::user()->id)->orderBy('created_at', 'desc')->get(); + $user = User::findOrFail($id); + $this->authorize('get-albums', $user); + + $query = Album::summary()->where('user_id', $id)->orderBy('created_at', 'desc')->get(); $albums = []; foreach ($query as $album) { $albums[] = [ diff --git a/app/Http/Controllers/Api/Web/TracksController.php b/app/Http/Controllers/Api/Web/TracksController.php index 70f39c2a..29ac29ff 100644 --- a/app/Http/Controllers/Api/Web/TracksController.php +++ b/app/Http/Controllers/Api/Web/TracksController.php @@ -183,9 +183,7 @@ class TracksController extends ApiControllerBase return $this->notFound('Track ' . $id . ' not found!'); } - if ($track->user_id != Auth::user()->id) { - return $this->notAuthorized(); - } + $this->authorize('edit', $track); return Response::json(Track::mapPrivateTrackShow($track), 200); } diff --git a/app/Http/routes.php b/app/Http/routes.php index f232a0f9..70b7a65f 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -137,7 +137,8 @@ Route::group(['prefix' => 'api/web'], function() { Route::get('/tracks/owned', 'Api\Web\TracksController@getOwned'); Route::get('/tracks/edit/{id}', 'Api\Web\TracksController@getEdit'); - Route::get('/albums/owned', 'Api\Web\AlbumsController@getOwned'); + Route::get('/users/{id}/albums', 'Api\Web\AlbumsController@getOwned')->where('id', '\d+'); +// Route::get('/albums/owned', 'Api\Web\AlbumsController@getOwned'); Route::get('/albums/edit/{id}', 'Api\Web\AlbumsController@getEdit'); Route::get('/playlists/owned', 'Api\Web\PlaylistsController@getOwned'); diff --git a/app/Models/Track.php b/app/Models/Track.php index 0dcfdd7e..cbfd510d 100644 --- a/app/Models/Track.php +++ b/app/Models/Track.php @@ -24,6 +24,7 @@ use Auth; use Cache; use Config; use DB; +use Gate; use Poniverse\Ponyfm\Contracts\Searchable; use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException; use Poniverse\Ponyfm\Traits\IndexedInElasticsearchTrait; @@ -423,8 +424,8 @@ class Track extends Model implements Searchable ], 'user_data' => $userData, 'permissions' => [ - 'delete' => Auth::check() && Auth::user()->id == $track->user_id, - 'edit' => Auth::check() && Auth::user()->id == $track->user_id + 'delete' => Gate::allows('delete', $track), + 'edit' => Gate::allows('edit', $track) ] ]; } diff --git a/app/Policies/AlbumPolicy.php b/app/Policies/AlbumPolicy.php new file mode 100644 index 00000000..a5836e65 --- /dev/null +++ b/app/Policies/AlbumPolicy.php @@ -0,0 +1,35 @@ +. + */ + +namespace Poniverse\Ponyfm\Policies; + +use Poniverse\Ponyfm\Models\Album; +use Poniverse\Ponyfm\Models\User; + +class AlbumPolicy +{ + public function edit(User $user, Album $album) { + return $user->id === $album->user_id || $user->hasRole('admin'); + } + + public function delete(User $user, Album $album) { + return $user->id === $album->user_id || $user->hasRole('admin'); + } +} diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php new file mode 100644 index 00000000..76d13507 --- /dev/null +++ b/app/Policies/UserPolicy.php @@ -0,0 +1,30 @@ +. + */ + +namespace Poniverse\Ponyfm\Policies; + +use Poniverse\Ponyfm\Models\User; + +class UserPolicy +{ + public function getAlbums(User $userToAuthorize, User $user) { + return $userToAuthorize->id === $user->id || $userToAuthorize->hasRole('admin'); + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 96b1b6c1..7656ba92 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -22,11 +22,14 @@ namespace Poniverse\Ponyfm\Providers; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Poniverse\Ponyfm\Models\Album; use Poniverse\Ponyfm\Models\Genre; +use Poniverse\Ponyfm\Policies\AlbumPolicy; use Poniverse\Ponyfm\Policies\GenrePolicy; use Poniverse\Ponyfm\Policies\TrackPolicy; use Poniverse\Ponyfm\Models\Track; use Poniverse\Ponyfm\Models\User; +use Poniverse\Ponyfm\Policies\UserPolicy; class AuthServiceProvider extends ServiceProvider { @@ -38,6 +41,8 @@ class AuthServiceProvider extends ServiceProvider protected $policies = [ Genre::class => GenrePolicy::class, Track::class => TrackPolicy::class, + Album::class => AlbumPolicy::class, + User::class => UserPolicy::class, ]; /** diff --git a/public/templates/directives/track-editor.html b/public/templates/directives/track-editor.html index 54a2f905..0cacf826 100644 --- a/public/templates/directives/track-editor.html +++ b/public/templates/directives/track-editor.html @@ -71,7 +71,7 @@ Show Songs: {{selectedSongsTitle}}
diff --git a/resources/assets/scripts/app/directives/track-editor.coffee b/resources/assets/scripts/app/directives/track-editor.coffee index f41eb8a8..31e83ff5 100644 --- a/resources/assets/scripts/app/directives/track-editor.coffee +++ b/resources/assets/scripts/app/directives/track-editor.coffee @@ -127,17 +127,19 @@ module.exports = angular.module('ponyfm').directive 'pfmTrackEditor', () -> # ======================================== # The part where everything gets loaded! # ======================================== - $.when( - albums.refresh(), - taxonomies.refresh(), - tracks.getEdit($scope.trackId, true) - ).done (albums, taxonomies, track)-> - # Update album data - $scope.albums.length = 0 - albumsDb = {} - for album in albums - albumsDb[album.id] = album - $scope.albums.push album + tracks.getEdit($scope.trackId, true) + .then (track)-> + $.when( + albums.refresh(false, track.user_id), + taxonomies.refresh() + ).done (albums, taxonomies)-> + # Update album data + $scope.albums.length = 0 + albumsDb = {} + for album in albums + albumsDb[album.id] = album + $scope.albums.push album + # Update track data diff --git a/resources/assets/scripts/app/services/account-albums.coffee b/resources/assets/scripts/app/services/account-albums.coffee index bcbdad03..ca6dd980 100644 --- a/resources/assets/scripts/app/services/account-albums.coffee +++ b/resources/assets/scripts/app/services/account-albums.coffee @@ -18,6 +18,9 @@ module.exports = angular.module('ponyfm').factory('account-albums', [ '$rootScope', '$http' ($rootScope, $http) -> def = null + # the ID of the user whose albums are currently cached + currentlyLoadedUserId = null + albums = [] self = @@ -31,11 +34,12 @@ module.exports = angular.module('ponyfm').factory('account-albums', [ $http.get(url).success (album) -> editDef.resolve album editDef.promise() - refresh: (force) -> - force = force || false - return def if !force && def + refresh: (force = false, user_id = window.pfm.auth.user.id) -> + return def if !force && def && user_id == currentlyLoadedUserId + def = new $.Deferred() - $http.get('/api/web/albums/owned').success (ownedAlbums) -> + $http.get("/api/web/users/#{user_id}/albums").success (ownedAlbums) -> + currentlyLoadedUserId = user_id def.resolve(ownedAlbums) def.promise() diff --git a/resources/assets/scripts/app/services/taxonomies.coffee b/resources/assets/scripts/app/services/taxonomies.coffee index bc16d6c1..55654ba7 100644 --- a/resources/assets/scripts/app/services/taxonomies.coffee +++ b/resources/assets/scripts/app/services/taxonomies.coffee @@ -27,6 +27,7 @@ module.exports = angular.module('ponyfm').factory('taxonomies', [ genresWithTracks: [] showSongs: [] showSongsWithTracks: [] + refresh: () -> return def.promise() if def != null