Allow filtering embedded albums/streams by author using data-author attribute#4083
Conversation
…ttribute This commit allows filtering embedded albums/streams by setting the data-author attribute to a Lychee user's username. Only that user's photos will be included in the embed. This feature was developed with Claude Code and tested manually.
📝 WalkthroughWalkthroughAdds author-based filtering to embed flows: frontend UI/config/types/API now accept an optional author, which is sent as a query parameter; backend request/controller and photo queries accept and apply author filters; new tests cover single, multi, non-existent author, and pagination behaviors. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
app/Http/Requests/Embed/EmbededRequest.php (1)
81-85: Consider adding length/character validation for theauthorparameter.The
authorvalue is user-supplied and used directly in a database query. While Laravel's query builder prevents SQL injection, there's no upper bound on string length. Consider trimming and capping it (e.g., 255 chars to match a typicalusernamecolumn length), consistent with howlimitandsortare validated above.💡 Suggested hardening
// Parse author filter $author = $this->query('author', null); - if ($author !== null && is_string($author) && $author !== '') { - $this->author = $author; + if ($author !== null && is_string($author) && $author !== '' && strlen($author) <= 255) { + $this->author = trim($author); }app/Http/Controllers/Gallery/EmbedController.php (1)
159-165: Author filter pattern inloadAlbumPhotosis functional but slightly duplicative.The
$author_filterclosure is clean. Note that$album->photos()->getQuery()is called twice (lines 163 and 165), producing two independent query builder instances. This is correct, but you could save a line by extracting a base query builder if desired. Not blocking.♻️ Optional: extract base query
private function loadAlbumPhotos(BaseAlbum $album, ?int $limit = null, int $offset = 0, ?string $sort = null, ?string $author = null): void { $author_filter = fn ($q) => $author !== null ? $q->whereHas('owner', fn ($q2) => $q2->where('username', $author)) : $q; - $total_photos = $author_filter($album->photos()->getQuery())->count(); - - $photos_query = $author_filter($album->photos()->getQuery()); + $base_query = fn () => $author_filter($album->photos()->getQuery()); + + $total_photos = $base_query()->count(); + $photos_query = $base_query();tests/Feature_v2/Embed/EmbedStreamTest.php (1)
323-339: Author-filter exclusion assertion is weak — photo1 is already in a private album.The assertion on line 338 checks that
photo1(owned byuserMayUpload1) is absent, butphoto1lives in a private album, so it would be excluded even without the author filter. This doesn't actually prove the filter works for the stream endpoint.Compare with
EmbedAlbumTest::testAuthorFilterReturnsOnlyMatchingPhotos(lines 181–210 inEmbedAlbumTest.php), which creates a second photo in the same public album owned by a different user, then verifies it is excluded. Consider the same approach here: factory-create a photo owned byuserMayUpload1inalbum4, assert it appears without the filter, and assert it's gone with the filter.Suggested approach
public function testAuthorFilterReturnsOnlyMatchingPhotos(): void { - // photo4 and subPhoto4 are public, both owned by userLocked - $response = $this->getJson('Embed/stream?author=' . $this->userLocked->username); + // Add a photo owned by a different user to the same public album + /** `@disregard` */ + $otherPhoto = Photo::factory()->owned_by($this->userMayUpload1)->with_GPS_coordinates()->in($this->album4)->create(); + + // Without author filter: should include the other user's photo + $response = $this->getJson('Embed/stream'); $this->assertOk($response); + $allPhotoIds = collect($response->json('photos'))->pluck('id')->toArray(); + $this->assertContains($otherPhoto->id, $allPhotoIds); + // With author filter: should return only userLocked's photos + $response = $this->getJson('Embed/stream?author=' . $this->userLocked->username); + $this->assertOk($response); $data = $response->json(); $photoIds = collect($data['photos'])->pluck('id')->toArray(); - // Photos owned by userLocked in public albums should be included $this->assertContains($this->photo4->id, $photoIds, 'photo4 owned by userLocked should be included'); $this->assertContains($this->subPhoto4->id, $photoIds, 'subPhoto4 owned by userLocked should be included'); + $this->assertNotContains($otherPhoto->id, $photoIds, 'otherPhoto owned by userMayUpload1 should be excluded'); - // Photos owned by other users should NOT be included (they are also in private albums, - // but the author filter should exclude them regardless) - $this->assertNotContains($this->photo1->id, $photoIds, 'photo1 owned by userMayUpload1 should not be included'); + $otherPhoto->delete(); }
Per review feedback from ildyria. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per review feedback from CodeRabbit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous test asserted that photo1 was excluded, but photo1 is in a private album and would be excluded regardless of the author filter. Now the test creates a photo by a different user in the same public album, verifying the author filter actually excludes it. Per review feedback from CodeRabbit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per review feedback from CodeRabbit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
This PR allows filtering embedded albums/streams by setting the data-author attribute to a Lychee user's username. Only that user's photos will be included in the embed.
As of 62fa810 , multiple usernames may be included in the
data-authorattribute, separated by commas.This feature was developed with Claude Code and tested manually.
Summary by CodeRabbit
New Features
Tests