Skip to content

Commit

Permalink
Add permission when user is not owner but creating an album. (#2298)
Browse files Browse the repository at this point in the history
* create failing test

* fix #2297

* fix phpstan

* WRTC
  • Loading branch information
ildyria authored Mar 2, 2024
1 parent bd3ade1 commit 9d20d22
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 10 deletions.
64 changes: 54 additions & 10 deletions app/Actions/Album/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace App\Actions\Album;

use App\Constants\AccessPermissionConstants as APC;
use App\Enum\DefaultAlbumProtectionType;
use App\Exceptions\ConfigurationKeyMissingException;
use App\Exceptions\ModelDBException;
use App\Exceptions\UnauthenticatedException;
use App\Exceptions\UnexpectedException;
use App\Models\AccessPermission;
use App\Models\Album;
use App\Models\Configs;
Expand All @@ -31,16 +34,7 @@ public function create(string $title, ?Album $parentAlbum): Album
$album->title = $title;
$this->set_parent($album, $parentAlbum);
$album->save();

$defaultProtectionType = Configs::getValueAsEnum('default_album_protection', DefaultAlbumProtectionType::class);

if ($defaultProtectionType === DefaultAlbumProtectionType::PUBLIC) {
$album->access_permissions()->saveMany([AccessPermission::ofPublic()]);
}

if ($defaultProtectionType === DefaultAlbumProtectionType::INHERIT && $parentAlbum !== null) {
$album->access_permissions()->saveMany($this->copyPermission($parentAlbum));
}
$this->set_permissions($album, $parentAlbum);

return $album;
}
Expand Down Expand Up @@ -68,6 +62,32 @@ private function set_parent(Album $album, ?Album $parentAlbum): void
}
}

/**
* Set up the permissions.
*
* @param Album $album
* @param Album|null $parentAlbum
*
* @return void
*
* @throws UnexpectedException
* @throws ConfigurationKeyMissingException
*/
private function set_permissions(Album $album, ?Album $parentAlbum): void
{
$defaultProtectionType = Configs::getValueAsEnum('default_album_protection', DefaultAlbumProtectionType::class);

if ($defaultProtectionType === DefaultAlbumProtectionType::PUBLIC) {
$album->access_permissions()->saveMany([AccessPermission::ofPublic()]);
}

if ($defaultProtectionType === DefaultAlbumProtectionType::INHERIT && $parentAlbum !== null) {
$album->access_permissions()->saveMany($this->copyPermission($parentAlbum));
}

$this->grantFullPermissionsToNewOwner($album);
}

/**
* Given a parent album, retrieve its access permission and return an array containing copies of them.
*
Expand All @@ -85,4 +105,28 @@ private function copyPermission(?Album $parentAlbum): array

return $copyPermissions;
}

/**
* If album is created by someone who has the album shared with.
* We need to give access all to that person.
*
* @param Album $album
*
* @return void
*/
private function grantFullPermissionsToNewOwner(Album $album)
{
if ($album->owner_id === $this->intendedOwnerId) {
return;
}

$album->access_permissions()
->where(APC::USER_ID, '=', $this->intendedOwnerId)
->where(APC::BASE_ALBUM_ID, '=', $album->id)
->delete();

$accessPerm = AccessPermission::withGrantFullPermissionsToUser($this->intendedOwnerId);

$album->access_permissions()->save($accessPerm);
}
}
19 changes: 19 additions & 0 deletions app/Models/AccessPermission.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,23 @@ public static function ofPublic(): self
APC::PASSWORD => null,
]);
}

/**
* Return a new permission set associated to a specific userId.
*
* @param int $userId
*
* @return AccessPermission
*/
public static function withGrantFullPermissionsToUser(int $userId): self
{
return new AccessPermission([
APC::USER_ID => $userId,
APC::GRANTS_FULL_PHOTO_ACCESS => true,
APC::GRANTS_DOWNLOAD => true,
APC::GRANTS_UPLOAD => true,
APC::GRANTS_EDIT => true,
APC::GRANTS_DELETE => true,
]);
}
}
53 changes: 53 additions & 0 deletions tests/Livewire/Forms/Album/CreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@

namespace Tests\Livewire\Forms\Album;

use App\Constants\AccessPermissionConstants as APC;
use App\Contracts\Livewire\Params;
use App\Livewire\Components\Forms\Album\Create;
use App\Livewire\Components\Forms\Album\ShareWith;
use App\Livewire\Components\Pages\Gallery\Album as GalleryAlbum;
use App\Models\AccessPermission;
use App\Models\Album;
use Livewire\Livewire;
use Tests\Livewire\Base\BaseLivewireTest;

Expand Down Expand Up @@ -57,4 +62,52 @@ public function testCreateLoggedIn(): void

$this->assertCount(2, $this->album1->fresh()->load('children')->children);
}

public function testCreateViaAccessRights(): void
{
$album = Album::factory()->as_root()->owned_by($this->admin)->create();

Livewire::actingAs($this->admin)->test(ShareWith::class, ['album' => $album])
->assertOk()
->set('userID', $this->userMayUpload1->id)
->set('grants_full_photo_access', true)
->set('grants_download', true)
->set('grants_upload', true)
->set('grants_edit', true)
->set('grants_delete', true)
->call('add')
->assertOk();

$num = AccessPermission::query()
->where(APC::BASE_ALBUM_ID, '=', $album->id)
->where(APC::USER_ID, '=', $this->userMayUpload1->id)
->count();

// we do have one permission
$this->assertEquals(1, $num);

Livewire::actingAs($this->userMayUpload1)->test(GalleryAlbum::class, ['albumId' => $album->id])
->assertOk();

$title = fake()->country() . ' ' . fake()->year();
Livewire::actingAs($this->userMayUpload1)->test(Create::class, ['params' => [Params::PARENT_ID => $album->id]])
->assertOk()
->assertViewIs('livewire.forms.add.create')
->set('title', $title)
->call('submit')
->assertRedirect();

/** @var Album $subAlbum */
$subAlbum = Album::query()
->select(['albums.*'])
->join('base_albums', 'base_albums.id', '=', 'albums.id')
->where('base_albums.title', '=', $title)->first();

Livewire::actingAs($this->userMayUpload1)->test(GalleryAlbum::class, ['albumId' => $subAlbum->id])
->assertOk();

Livewire::actingAs($this->userMayUpload1)->test(GalleryAlbum::class, ['albumId' => $album->id])
->assertOk()
->assertSee($title);
}
}

0 comments on commit 9d20d22

Please sign in to comment.