#71, #111: Implemented security checking in the JSON feed methods. Also users now automatically inherit the anonymous permissions by way of an additional check specifically against the anonymous user first
This commit is contained in:
parent
2394bbd077
commit
f36aa61506
@ -16,6 +16,25 @@ class PermissionsHelper
|
|||||||
public function getAlbumIDs($permission = 'list', User $user = null)
|
public function getAlbumIDs($permission = 'list', User $user = null)
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
|
// First check if the anonymous user can do what is being requested - if so, the permission would also inherit
|
||||||
|
// to logged-in users
|
||||||
|
$anonymousUsersCan = DB::table('album_permissions_cache')
|
||||||
|
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
||||||
|
->where([
|
||||||
|
['album_permissions_cache.user_id', null],
|
||||||
|
['permissions.section', 'album'],
|
||||||
|
['permissions.description', $permission]
|
||||||
|
])
|
||||||
|
->select('album_permissions_cache.album_id')
|
||||||
|
->distinct()
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($anonymousUsersCan as $item)
|
||||||
|
{
|
||||||
|
$result[] = $item->album_id;
|
||||||
|
}
|
||||||
|
|
||||||
$query = DB::table('album_permissions_cache')
|
$query = DB::table('album_permissions_cache')
|
||||||
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
||||||
->where([
|
->where([
|
||||||
@ -28,9 +47,12 @@ class PermissionsHelper
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach ($query as $item)
|
foreach ($query as $item)
|
||||||
|
{
|
||||||
|
if (!in_array($item->album_id, $result))
|
||||||
{
|
{
|
||||||
$result[] = $item->album_id;
|
$result[] = $item->album_id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@ -42,6 +64,23 @@ class PermissionsHelper
|
|||||||
|
|
||||||
public function userCan_Album(Album $album, User $user, $permission)
|
public function userCan_Album(Album $album, User $user, $permission)
|
||||||
{
|
{
|
||||||
|
// First check if the anonymous user can do what is being requested - if so, the permission would also inherit
|
||||||
|
// to logged-in users
|
||||||
|
$anonymousUsersCan = DB::table('album_permissions_cache')
|
||||||
|
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
||||||
|
->where([
|
||||||
|
['album_permissions_cache.album_id', $album->id],
|
||||||
|
['album_permissions_cache.user_id', null],
|
||||||
|
['permissions.section', 'album'],
|
||||||
|
['permissions.description', $permission]
|
||||||
|
])
|
||||||
|
->count() > 0;
|
||||||
|
|
||||||
|
if ($anonymousUsersCan)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return DB::table('album_permissions_cache')
|
return DB::table('album_permissions_cache')
|
||||||
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id')
|
||||||
->where([
|
->where([
|
||||||
|
@ -23,6 +23,7 @@ use App\Services\AlbumService;
|
|||||||
use App\Services\PhotoService;
|
use App\Services\PhotoService;
|
||||||
use App\Storage;
|
use App\Storage;
|
||||||
use App\User;
|
use App\User;
|
||||||
|
use App\UserActivity;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@ -698,6 +699,9 @@ class AlbumController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add an activity record
|
||||||
|
$this->createActivityRecord($album, 'album.created');
|
||||||
|
|
||||||
// Rebuild the permissions cache
|
// Rebuild the permissions cache
|
||||||
$helper = new PermissionsHelper();
|
$helper = new PermissionsHelper();
|
||||||
$helper->rebuildCache();
|
$helper->rebuildCache();
|
||||||
@ -782,6 +786,21 @@ class AlbumController extends Controller
|
|||||||
return redirect(route('albums.show', ['id' => $id]));
|
return redirect(route('albums.show', ['id' => $id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createActivityRecord(Album $album, $type, $activityDateTime = null)
|
||||||
|
{
|
||||||
|
if (is_null($activityDateTime))
|
||||||
|
{
|
||||||
|
$activityDateTime = new \DateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
$userActivity = new UserActivity();
|
||||||
|
$userActivity->user_id = $this->getUser()->id;
|
||||||
|
$userActivity->activity_at = $activityDateTime;
|
||||||
|
$userActivity->type = $type;
|
||||||
|
$userActivity->album_id = $album->id;
|
||||||
|
$userActivity->save();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $id
|
* @param $id
|
||||||
* @return Album
|
* @return Album
|
||||||
|
@ -70,8 +70,31 @@ class UserController extends Controller
|
|||||||
$params = [];
|
$params = [];
|
||||||
$params['user_name'] = $userName;
|
$params['user_name'] = $userName;
|
||||||
$params['user_url'] = $userProfileUrl;
|
$params['user_url'] = $userProfileUrl;
|
||||||
|
|
||||||
|
if (!is_null($activity->photo))
|
||||||
|
{
|
||||||
|
// Check the user has access
|
||||||
|
if (!$this->getUser()->can('view', $activity->photo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$params['photo_name'] = $activity->photo->name;
|
$params['photo_name'] = $activity->photo->name;
|
||||||
$params['photo_url'] = $activity->photo->url();
|
$params['photo_url'] = $activity->photo->url();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($activity->album))
|
||||||
|
{
|
||||||
|
// Check the user has access
|
||||||
|
if (!$this->getUser()->can('view', $activity->album))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params['album_name'] = $activity->album->name;
|
||||||
|
$params['album_url'] = $activity->album->url();
|
||||||
|
}
|
||||||
|
|
||||||
$newItem['params'] = $params;
|
$newItem['params'] = $params;
|
||||||
|
|
||||||
$result[] = $newItem;
|
$result[] = $newItem;
|
||||||
@ -238,6 +261,7 @@ class UserController extends Controller
|
|||||||
$result = [];
|
$result = [];
|
||||||
$activities = UserActivity::with('photo')
|
$activities = UserActivity::with('photo')
|
||||||
->with('photoComment')
|
->with('photoComment')
|
||||||
|
->with('album')
|
||||||
->where([
|
->where([
|
||||||
'user_id' => $user->id
|
'user_id' => $user->id
|
||||||
])
|
])
|
||||||
@ -261,8 +285,31 @@ class UserController extends Controller
|
|||||||
$params = [];
|
$params = [];
|
||||||
$params['user_name'] = $userName;
|
$params['user_name'] = $userName;
|
||||||
$params['user_url'] = $userProfileUrl;
|
$params['user_url'] = $userProfileUrl;
|
||||||
|
|
||||||
|
if (!is_null($activity->photo))
|
||||||
|
{
|
||||||
|
// Check the user has access
|
||||||
|
if (!$this->getUser()->can('view', $activity->photo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$params['photo_name'] = $activity->photo->name;
|
$params['photo_name'] = $activity->photo->name;
|
||||||
$params['photo_url'] = $activity->photo->url();
|
$params['photo_url'] = $activity->photo->url();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($activity->album))
|
||||||
|
{
|
||||||
|
// Check the user has access
|
||||||
|
if (!$this->getUser()->can('view', $activity->album))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params['album_name'] = $activity->album->name;
|
||||||
|
$params['album_url'] = $activity->album->url();
|
||||||
|
}
|
||||||
|
|
||||||
$newItem['params'] = $params;
|
$newItem['params'] = $params;
|
||||||
|
|
||||||
$result[] = $newItem;
|
$result[] = $newItem;
|
||||||
|
@ -83,4 +83,15 @@ class PhotoPolicy
|
|||||||
|
|
||||||
return $user->can('post-comment', $photo->album);
|
return $user->can('post-comment', $photo->album);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function view(User $user, Photo $photo)
|
||||||
|
{
|
||||||
|
if ($user->id == $photo->user_id)
|
||||||
|
{
|
||||||
|
// The photo's owner can do everything
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user->can('view', $photo->album);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,11 @@ class UserActivity extends Model
|
|||||||
{
|
{
|
||||||
protected $table = 'user_activity';
|
protected $table = 'user_activity';
|
||||||
|
|
||||||
|
public function album()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Album::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function photo()
|
public function photo()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Photo::class);
|
return $this->belongsTo(Photo::class);
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddAlbumActivityColumn extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('user_activity', function (Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->unsignedInteger('album_id')->nullable(true);
|
||||||
|
|
||||||
|
$table->foreign('album_id')
|
||||||
|
->references('id')->on('albums')
|
||||||
|
->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('user_activity', function (Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('user_activity_album_id_foreign');
|
||||||
|
$table->dropColumn('album_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -181,6 +181,16 @@ function UserViewModel(urls)
|
|||||||
'<a href="' + data[i].params.photo_url + '">' + data[i].params.photo_name + '</a>'
|
'<a href="' + data[i].params.photo_url + '">' + data[i].params.photo_name + '</a>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Album name
|
||||||
|
if (data[i].params.album_name && data[i].params.album_url)
|
||||||
|
{
|
||||||
|
data[i].description = data[i].description
|
||||||
|
.replace(
|
||||||
|
':album_name',
|
||||||
|
'<a href="' + data[i].params.album_url + '">' + data[i].params.album_name + '</a>'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.feed_items = data;
|
self.feed_items = data;
|
||||||
|
@ -93,6 +93,9 @@ return [
|
|||||||
'title' => 'My Activity Feed'
|
'title' => 'My Activity Feed'
|
||||||
],
|
],
|
||||||
'user_feed_type' => [
|
'user_feed_type' => [
|
||||||
|
'album' => [
|
||||||
|
'created' => ':user_name created the :album_name album.'
|
||||||
|
],
|
||||||
'photo' => [
|
'photo' => [
|
||||||
'comment_replied' => ':user_name replied to a comment on the :photo_name photo.',
|
'comment_replied' => ':user_name replied to a comment on the :photo_name photo.',
|
||||||
'commented' => ':user_name commented on the :photo_name photo.',
|
'commented' => ':user_name commented on the :photo_name photo.',
|
||||||
|
Loading…
Reference in New Issue
Block a user