diff --git a/app/Actions/Album/Create.php b/app/Actions/Album/Create.php index c323adb28b1..29fc4d249c0 100644 --- a/app/Actions/Album/Create.php +++ b/app/Actions/Album/Create.php @@ -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; @@ -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; } @@ -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. * @@ -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); + } } diff --git a/app/Models/AccessPermission.php b/app/Models/AccessPermission.php index ec707497110..31b75c8c114 100644 --- a/app/Models/AccessPermission.php +++ b/app/Models/AccessPermission.php @@ -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, + ]); + } } \ No newline at end of file diff --git a/tests/Livewire/Forms/Album/CreateTest.php b/tests/Livewire/Forms/Album/CreateTest.php index 93927d0f292..d997d2bfc58 100644 --- a/tests/Livewire/Forms/Album/CreateTest.php +++ b/tests/Livewire/Forms/Album/CreateTest.php @@ -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; @@ -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); + } }