Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gallery permission rework #775

Merged
merged 10 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/Http/Controllers/Campaign/GalleryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function show(Campaign $campaign)
*/
public function store(GalleryImageStore $request, Campaign $campaign)
{
$this->authorize('gallery', $campaign);
$this->authorize('create', [Image::class, $campaign]);

$images = $this->service
->campaign($campaign)
Expand Down Expand Up @@ -80,7 +80,7 @@ public function store(GalleryImageStore $request, Campaign $campaign)
*/
public function edit(Campaign $campaign, Image $image)
{
$this->authorize('gallery', $campaign);
$this->authorize('view', [$image, $campaign]);

$folders = $this->service->campaign($campaign)->folderList();

Expand All @@ -93,7 +93,7 @@ public function edit(Campaign $campaign, Image $image)
*/
public function update(GalleryImageUpdate $request, Campaign $campaign, Image $image)
{
$this->authorize('gallery', $campaign);
$this->authorize('edit', [$image, $campaign]);

$originalFolderID = $image->folder_id;
$this->service
Expand Down Expand Up @@ -122,7 +122,7 @@ public function update(GalleryImageUpdate $request, Campaign $campaign, Image $i
*/
public function destroy(Campaign $campaign, Image $image)
{
$this->authorize('gallery', $campaign);
$this->authorize('delete', [$image, $campaign]);

$options = [$campaign];
if ($image->folder_id) {
Expand Down
19 changes: 12 additions & 7 deletions app/Http/Controllers/Campaign/RoleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@
use App\Http\Requests\StoreCampaignRole;
use App\Models\Campaign;
use App\Models\CampaignRole;
use App\Services\PermissionService;
use App\Services\Permissions\RolePermissionService;
use Illuminate\Http\Request;

class RoleController extends Controller
{
protected string $view = 'campaigns.roles';

protected PermissionService $service;
protected RolePermissionService $service;

/**
* Create a new controller instance.
* @return void
*/
public function __construct(PermissionService $permissionService)
public function __construct(RolePermissionService $rolePermissionService)
{
$this->middleware('auth');
$this->middleware('campaign.member');
$this->service = $permissionService;
$this->service = $rolePermissionService;
}

/**
Expand Down Expand Up @@ -111,7 +111,11 @@ public function store(StoreCampaignRole $request, Campaign $campaign)
$data = $request->all() + ['campaign_id' => $campaign->id];
$role = CampaignRole::create($data);
if ($request->has('duplicate') && $request->get('duplicate') != 0) {
$this->service->role($role)->duplicate($request->get('role_id'));
/** @var CampaignRole $copy */
$copy = CampaignRole::where('id', $request->get('role_id'))->first();
if ($copy) {
$copy->duplicate($role);
}
}
return redirect()->route('campaign_roles.index', $campaign)
->with('success_raw', __($this->view . '.create.success', ['name' => $role->name]));
Expand All @@ -132,6 +136,7 @@ public function show(Campaign $campaign, CampaignRole $campaignRole)
'role' => $campaignRole,
'campaign' => $campaign,
'members' => $members,
'permissionService' => $this->service->role($campaignRole)
]);
}

Expand Down Expand Up @@ -176,7 +181,7 @@ public function savePermissions(Request $request, Campaign $campaign, CampaignRo
$this->authorize('view', [$campaignRole, $campaign]);
$this->authorize('update', $campaignRole);

$campaignRole->savePermissions($request->post('permissions', []));
$this->service->role($campaignRole)->savePermissions($request->post('permissions', []));

return redirect()->route('campaign_roles.show', [$campaign, 'campaign_role' => $campaignRole])
->with('success', trans('crud.permissions.success'));
Expand Down Expand Up @@ -249,7 +254,7 @@ public function toggle(Campaign $campaign, CampaignRole $campaignRole, int $enti
abort(404);
}

$enabled = $campaignRole->toggle($entityType, $action);
$enabled = $this->service->role($campaignRole)->toggle($entityType, $action);
return response()->json([
'success' => true,
'status' => $enabled,
Expand Down
6 changes: 4 additions & 2 deletions app/Http/Controllers/Summernote/GalleryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public function index(Campaign $campaign)
'url' => route('campaign.gallery.summernote', $image->folder_id ? [$campaign, 'folder_id' => $image->folder_id] : [$campaign]),
];
}
$images = Image::where('is_default', false)
$canBrowse = auth()->user()->can('browse', [Image::class, $campaign]);
$images = Image::acl($canBrowse)
->where('is_default', false)
->orderBy('is_folder', 'desc')
->orderBy('updated_at', 'desc')
->imageFolder($folderId)
Expand Down Expand Up @@ -85,7 +87,7 @@ public function index(Campaign $campaign)
*/
public function upload(GalleryImageStore $request, Campaign $campaign): JsonResponse
{
$this->authorize('gallery', $campaign);
$this->authorize('create', [Image::class, $campaign]);

$images = $this->service
->campaign($campaign)
Expand Down
20 changes: 15 additions & 5 deletions app/Models/CampaignPermission.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ class CampaignPermission extends Model
public const ACTION_GALLERY = 13;
public const ACTION_CAMPAIGN = 14;

/**
* @var bool|array
*/
protected $cachedSegments = false;
public const ACTION_GALLERY_BROWSE = 15;
public const ACTION_GALLERY_UPLOAD = 16;

protected array $cachedSegments;

/** @var string[] */
protected $fillable = [
Expand Down Expand Up @@ -152,7 +152,7 @@ public function type()

protected function segments(): array
{
if ($this->cachedSegments === false) {
if (!isset($this->cachedSegments)) {
$this->cachedSegments = explode('_', $this->key);
}
return $this->cachedSegments;
Expand Down Expand Up @@ -213,4 +213,14 @@ public function invalidKey(): bool
$end = last($segments);
return is_numeric($end) && empty($this->entity_id);
}

public function isGallery(): bool
{
$galleryPermissions = [
self::ACTION_GALLERY,
self::ACTION_GALLERY_BROWSE,
self::ACTION_GALLERY_UPLOAD,
];
return in_array($this->action, $galleryPermissions);
}
}
88 changes: 8 additions & 80 deletions app/Models/CampaignRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;

/**
* Class Attribute
Expand Down Expand Up @@ -131,49 +130,6 @@ public function rolePermissions()
->whereNull('entity_id');
}

/**
*/
public function savePermissions(array $permissions = [])
{
// Load existing
$existing = [];
foreach ($this->rolePermissions as $permission) {
if (empty($permission->entity_type_id)) {
$existing['campaign_' . $permission->action] = $permission;
continue;
}
$existing[$permission->entity_type_id . '_' . $permission->action] = $permission;
}

// Loop on submitted form
if (empty($permissions)) {
$permissions = [];
}

foreach ($permissions as $key => $module) {
// Check if exists$
if (isset($existing[$key])) {
// Do nothing
unset($existing[$key]);
} else {
$action = Str::after($key, '_');
if ($module === 'campaign') {
$module = 0;
}

$this->add($module, (int) $action);
}
}

// Delete existing that weren't updated
foreach ($existing as $permission) {
// Only delete if it's a "general" and not an entity specific permission
if (!is_numeric($permission->entityId())) {
$permission->delete();
}
}
}

/**
*/
public function scopeSearch(Builder $builder, string $search = null): Builder
Expand All @@ -183,47 +139,19 @@ public function scopeSearch(Builder $builder, string $search = null): Builder
}

/**
* Toggle an entity's action permission
*/
public function toggle(int $entityType, int $action): bool
public function url(string $sub): string
{
$perm = $this->permissions()
->where('entity_type_id', $entityType)
->where('action', $action)
->whereNull('entity_id')
->first();

if ($perm) {
$perm->delete();
return false;
}

$this->add($entityType, $action);
return true;
return 'campaign_roles.' . $sub;
}

/**
* Add a campaign permission for the role
*/
protected function add(int $entityType, int $action): CampaignPermission
public function duplicate(CampaignRole $campaignRole): self
{
if ($entityType === 0) {
$entityType = null;
foreach ($this->permissions as $permission) {
$newPermission = $permission->replicate(['campaign_role_id']);
$newPermission->campaign_role_id = $campaignRole->id;
$newPermission->save();
}
return CampaignPermission::create([
//'key' => $key,
'campaign_role_id' => $this->id,
//'table_name' => $value,
'access' => true,
'action' => $action,
'entity_type_id' => $entityType
//'campaign_id' => $campaign->id,
]);
}
/**
*/
public function url(string $sub): string
{
return 'campaign_roles.' . $sub;
return $this;
}
}
28 changes: 28 additions & 0 deletions app/Models/EntityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
/**
* @property int $id
* @property string $code
*
* @method static self|Builder exclude(array $ids)
*/
class EntityType extends Model
{
protected string $cachedPluralCode;

public $fillable = [
'id',
'code',
Expand All @@ -30,6 +34,11 @@ public function scopeEnabled(Builder $query)
->orderBy('position');
}

public function scopeExclude(Builder $query, array $exclude): Builder
{
return $query->whereNotIn('id', $exclude);
}

/**
* Get the class model of the entity type
*/
Expand All @@ -47,6 +56,25 @@ public function name(): string
return Module::singular($this->id, __('entities.' . $this->code));
}

/**
* Get the translated name of the entity
*/
public function plural(): string
{
return Module::plural($this->id, __('entities.' . $this->pluralCode()));
}

/**
* Get the translated name of the entity
*/
public function pluralCode(): string
{
if (isset($this->cachedPluralCode)) {
return $this->cachedPluralCode;
}
return $this->cachedPluralCode = Str::plural($this->code);
}

/**
*/
public function getNameAttribute(): string
Expand Down
10 changes: 10 additions & 0 deletions app/Models/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
*
*
* @property int $_usageCount
*
* @method static Builder|self acl(bool $browse)
*/
class Image extends Model
{
Expand Down Expand Up @@ -225,6 +227,14 @@ public function scopeFolders(Builder $query): Builder
->orderBy('name', 'asc');
}

public function scopeAcl(Builder $query, bool $browse): Builder
{
if (!$browse) {
return $query->where('created_by', auth()->user()->id);
}
return $query;
}

/**
*/
public function hasNoFolders(): bool
Expand Down
1 change: 1 addition & 0 deletions app/Models/Quest.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public function scopePreparedWith(Builder $query): Builder
'entity',
'entity.image',
'entity.calendarDateEvents',
'entity.calendarDate',
'quests',
'instigator',
//'elements',
Expand Down
8 changes: 8 additions & 0 deletions app/Models/Relations/CampaignRelations.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ public function members()
return $this->hasMany('App\Models\CampaignUser');
}

public function nonAdmins()
{
return $this
->members()
->withoutAdmins()
->with(['user', 'user.campaignRoles'])
;
}
/**
*/
public function roles()
Expand Down
4 changes: 3 additions & 1 deletion app/Policies/CampaignPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ public function submissions(?User $user)
public function gallery(?User $user, Campaign $campaign): bool
{
return $user && (
UserCache::user($user)->admin() || $this->checkPermission(CampaignPermission::ACTION_GALLERY, $user, $campaign)
UserCache::user($user)->admin() ||
$this->checkPermission(CampaignPermission::ACTION_GALLERY, $user, $campaign) ||
$this->checkPermission(CampaignPermission::ACTION_GALLERY_BROWSE, $user, $campaign)
);
}

Expand Down
Loading