fix: filter repos by project is_public on browse frontend (#58) #59
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-api!59
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "58-fix-repos-public-filter"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
is_publicon landing page (/browse/) and/browse/repos_apply_repo_public_filterhelper following existing_apply_project_public_filterpattern_apply_project_public_filterto projects query on/browse/repos(was unfiltered)project_id) remain visible to all visitorsChanges
src/pal_e_docs/routes/frontend.py: Added_apply_repo_public_filterhelper that usesouterjointhroughRepo.projectand filters byProject.is_publicwhen user is None. Applied to landing page and/browse/reposrepos queries. Applied existing_apply_project_public_filterto/browse/reposprojects query.tests/test_repo_public_filter.py: 6 new tests verifying repos and projects are filtered for unauthenticated visitors and visible for authenticated users on both/browse/and/browse/repos.Test Plan
/browse/unauthenticated, confirm private project repos hidden/browse/reposunauthenticated, confirm private project repos and projects hiddenReview Checklist
frontend.pyand the new test fileproject_idgracefully (outerjoin)ruff formatandruff checkpassRelated Notes
plan-2026-02-28-knowledge-system-consolidationPhase 4 (Privacy Audit)issue-pal-e-docs-repos-public-filterPR #59 Review
BLOCKERS
None.
NITS
Missing test for repos with NULL
project_id: The_apply_repo_public_filterhelper explicitly handlesRepo.project_id.is_(None)via the outerjoin, but no test seeds a repo without a project to verify it remains visible to unauthenticated visitors. Consider adding a test that creates a repo with noproject_slugand asserts it appears on both/browse/and/browse/reposfor unauthenticated users. The logic is correct, but a regression test would lock it in._create_usersession management: The_create_userhelper intest_repo_public_filter.pywraps the session intry/finallywithdb.close(), but does not calldb.rollback()on failure before closing. Ifdb.commit()raises, the session is closed without rollback. In practice this is harmless with the in-memory SQLite test setup, but for consistency with defensive patterns, atry/exceptwith rollback would be cleaner.SOP COMPLIANCE
58-fix-repos-public-filterreferences issue #58)template-pr-body(Summary, Changes, Test Plan, Review Checklist, Related Notes)plan-2026-02-28-knowledge-system-consolidation)issue-pal-e-docs-repos-public-filter)frontend.py+ new test file)Code Quality Notes
_apply_repo_public_filterhelper correctly follows the existing_apply_project_public_filterpattern.outerjoin(Repo.project)is the right choice: repos with NULLproject_idare preserved, and each repo has at most one project, so no duplicate rows.outerjoinfor filtering andsubqueryloadfor eager loading coexist correctly (subqueryload issues a separate query).db.query(Repo)are covered (landingandbrowse_repos).db.query(Project)on/browse/reposis also fixed -- good catch, as therepos.htmltemplate groups repos by project.VERDICT: APPROVED
PR #59 Review
BLOCKERS
None.
NITS
None.
Code Review Details
Correctness -- The
_apply_repo_public_filterhelper is well-implemented:outerjoin(Repo.project)so repos withNULL project_idare preserved (not excluded by an inner join).(Repo.project_id.is_(None)) | (Project.is_public.is_(True))correctly shows orphan repos and public-project repos while hiding private-project repos.Repo.projectis many-to-one (at most one project per repo), so the outerjoin cannot fan out.outerjoin(filtering) andsubqueryload(Repo.project)(eager loading) -- they operate independently.Completeness -- All browse frontend repo queries are covered:
/browse/(landing) -- filtered./browse/repos-- both repos and projects queries filtered./browse/projects/{slug}does NOT listRepoobjects (only the project's ownrepo_url), so no leakage path there.routes/repos.py) remains unfiltered, but that is a known pre-existing condition (no auth on the API at all, tracked in issue #2) and outside this PR's scope.Tests -- 8 tests covering all cases:
/browse/repos: private projects hidden for unauthenticated, visible for authenticated.project_id): visible to unauthenticated on both landing and repos page._create_user,_login,_seed_repos,_get_test_db) follow existing patterns fromtest_project_schema.pyandtest_auth.py.Security -- No data leakage paths identified. No secrets committed. Dummy test credentials (
secret123) match existing test patterns.Code Quality -- Clean, minimal diff. Follows the existing
_apply_*_public_filternaming convention. Docstring is accurate. Only 2 files changed (source + tests), no scope creep.SOP COMPLIANCE
58-fix-repos-public-filter-> issue #58)template-pr-body(Summary, Changes, Test Plan, Review Checklist, Related Notes)plan-2026-02-28-knowledge-system-consolidation)VERDICT: APPROVED
67421c4b2c1858c04f1f