Skip to content

Dedupe observable/entity/indicator get-by-name/value endpoints (item #5, third slice) - #1335

Merged
tomchop merged 1 commit into
mainfrom
fix/dedupe-get-by-name-endpoint
Jul 30, 2026
Merged

Dedupe observable/entity/indicator get-by-name/value endpoints (item #5, third slice)#1335
tomchop merged 1 commit into
mainfrom
fix/dedupe-get-by-name-endpoint

Conversation

@tomchop

@tomchop tomchop commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Third incremental slice of item #5 (observable/entity/indicator router
triplication), following #1333 (tag endpoint) and #1334 (details/delete
endpoints). This one covers the GET / (find-by-value/name) endpoint.

Each router's get endpoint built a lookup dict, called the model's
find(), raised 404 if nothing matched, called get_tags(), then ran the
identical RBAC read-permission check (admin/RBAC-disabled bypass, else
has_permissions check raising 403) before returning. The only real
differences were the not-found message wording and the query parameter
name itself — value for observable, name for entity/indicator.

Change

Added core/web/apiv2/crud.py::get_by_lookup(), taking the base type, an
already-built lookup dict, and the not-found message; it performs the
find() call plus the shared not-found/tags/RBAC logic. Each router's
get endpoint still builds its own lookup dict — preserving the exact
per-type "only include type in the query if set" behavior and, crucially,
keeping the differing query parameter name (value/name) in its own
function signature, since that's part of the OpenAPI contract and not
something to unify.

OpenAPI spec verified byte-identical (md5 match between a throwaway
pre-change build and the post-change build, same method used for the
previous two slices).

No incidental bugs found this time — all three endpoints already agreed
on status codes and message format, unlike the tag/delete endpoints fixed
in #1333/#1334.

Test plan

  • Full tests/apiv2 suite: 201/203 pass (same 2 known pre-existing
    failures in tests/apiv2/tasks.py, unrelated) — includes the
    existing get-by-value/name and RBAC-forbidden tests for all three
    routers, unchanged.
  • tests/schemas (190/190) and tests/core_tests (31/31) pass
    unchanged.
  • ty check (core+yetictl and plugins jobs): 0 errors.
  • ruff check / ruff format --check: clean.

Scope note

The one remaining item #5 candidate from the original list — the search
endpoint body — is the most entangled: entity/indicator support
filter_aliases and a separate get_multiple endpoint that observable
has neither of. Normalizing that safely needs a real design decision
(add the missing fields to observable's search, changing its OpenAPI
shape — additive but deliberate) rather than a blind extraction, so I'd
treat it as its own follow-up rather than bundling it here.

…dies

Third slice of item #5's router dedup. The GET / (find-by-value/name)
endpoint on each router built a lookup dict, called the model's find(),
raised 404 if nothing matched, called get_tags(), then ran the same
RBAC read-permission check (admin/RBAC-disabled bypass, else check
has_permissions and raise 403) before returning. Identical logic across
all three, save for the not-found message wording and the query
parameter name itself (value for observable, name for entity/
indicator) -- the latter stays in each router's own function signature
since it's part of the OpenAPI contract, not something to unify.

Add core/web/apiv2/crud.py::get_by_lookup(), taking the base type, the
already-built lookup dict, and the not-found message; it does the
find() call plus the shared not-found/tags/RBAC logic. Each router's
`get` endpoint still builds its own lookup dict (preserving the exact
per-type "only include type in the query if set" behavior) and passes
it straight through -- no behavior change, verified via a byte-for-byte
OpenAPI diff (md5 match, throwaway pre/post build) same as the earlier
two slices.

No incidental bugs found this time -- all three endpoints already
agreed on status codes and message format, unlike the tag/delete
endpoints fixed in #1333/#1334.
@tomchop
tomchop merged commit b0480e2 into main Jul 30, 2026
5 checks passed
@tomchop
tomchop deleted the fix/dedupe-get-by-name-endpoint branch July 30, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant