Skip to content

Paged repo-list owner filter misses bare-owner mirror rows when given a full DID #102

Description

@beardthelion

The paged GET /api/v1/repos?owner=…&limit=… filter and the non-paged list path disagree on how they match an owner DID, so the same owner= query can return different repos depending on whether limit is set.

Root cause

list_all_repos_paged filters in SQL (crates/gitlawb-node/src/db/mod.rs:911):

WHERE ($1::text IS NULL OR owner_did = $1 OR owner_did LIKE '%:' || $1)

query.owner comes straight from the HTTP query string (crates/gitlawb-node/src/api/repos.rs:215), so a client can pass a full did:key:z6Mk…. When it does:

  • owner_did = 'did:key:z6MkX' matches a canonical row.
  • owner_did LIKE '%:did:key:z6MkX' matches nothing useful: a bare-owner mirror row stored as z6MkX has no colon, so it does not match.

So a mirror-only repo (bare owner, no canonical row on this node) is omitted from the paged listing when filtered by a full DID.

The non-paged path filters in Rust with did_matches (crates/gitlawb-node/src/api/mod.rs:63), which matches full and short DID forms in both directions, so it returns that mirror row. The two list surfaces diverge on full-DID input.

The short-form case works on both paths: owner=z6MkX -> owner_did = 'z6MkX' matches the bare row and LIKE '%:z6MkX' matches did:key:z6MkX.

Reachability

Reachable from an unauthenticated GET /api/v1/repos?owner=did:key:z6Mk…&limit=50. The bug under-returns rows; it does not over-expose anything, hence sev:low.

Scope

Deferred follow-up from #73 (jatmn flagged it there as optional/pre-existing, out of scope for that PR). Pre-existing, not introduced by #73. The same loose LIKE '%:' || $1 || '%' pattern also appears at db/mod.rs:834 (lookup by owner+name) and is worth checking for the same divergence.

Fix direction

Route the paged SQL owner filter through the same full+short DID logic the Rust did_matches path uses, so both list surfaces agree for any DID form. Add a regression test: a bare-owner mirror row must appear in the paged listing when filtered by the full did:key:… form. Confirm the owner+name query at db/mod.rs:834 is consistent too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:nodegitlawb-node — the serving node and REST APIkind:bugDefect fix — wrong or unsafe behaviorsev:lowCosmetic, cleanup, or nice-to-havesubsystem:replicationMirror, replica, and cross-node sync

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions