- Add _validate_json_path(): each __-separated path segment must match
[A-Za-z0-9_][A-Za-z0-9_-]* (allows leading underscores per Jeremy's
suggestion; ORM operator names like 'date'/'regex' are valid JSON keys
and are not blocked — the trailing __ JSONFilter appends makes them
key traversal steps, not ORM transforms)
- Add JSONStringLookup: explicit string-filter type for JSONLookup.
regex/i_regex are included (they offer no additional oracle power
beyond starts_with, which is also present, per Jeremy's observation)
- JSONFilter.filter() validates self.path and returns empty Q() on
invalid input rather than passing untrusted user input to the ORM
- 19 unit tests for path validation and JSONStringLookup field presence
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update strawberry-graphql-django to 0.86.1 and remove redundant type
parameters from StrFilterLookup, DateFilterLookup, TimeFilterLookup, and
DatetimeFilterLookup annotations across model-backed GraphQL filters.
Add NetBox-local JSON date, time, and datetime lookup input types to
preserve the previous string-backed JSON filter schema without relying
on deprecated upstream generic lookup annotations. These local types
keep the legacy GraphQL type names and date/time sub-lookup fields
intact.
Fixes#22353
The method wrote uploaded files to disk via a raw open(), but no code
path reached it. Its only subclass, ScriptFileForm, overrode save() to
write through django-storages and explicitly skipped the base via
super(ManagedFileForm, self).save(). With the override gone, that call
simplifies back to a plain super().save(). A leftover from #18680, which
moved both upload paths onto django-storages but left the form-level
write in place.
Change `get_schema_extensions()` to return extension factories instead
of instances. This defers extension initialization and prevents stale
references to settings captured at import time.
Lambdas capture settings values when extensions are constructed, and
tests now instantiate extensions from factories to verify configuration.
Fixes#22451
The test failures arises from unstable sorting of the usernames
depending on the collation used in the PostgreSQL database used for
testing. When a case-insensitive collation is used 'testuser' is sorted
before 'User*' and because this user has permissions assigned and
additional query is issued resulting in 12 queries. When a
case-sensitive collation is used the sorting is inverted. Because the
'User*' don't have permissions only 11 queries are sent to the database.
Using only testusers with lowercase names enforces stable sorting
across collations.
Replace IPSet-heavy Prefix availability and utilization logic with
indexed host lookups, distinct host counts, and interval-based
availability calculation.
This adds mask-insensitive host-bound filtering for IP addresses and
ranges, moves availability/counting behavior onto QuerySet and model
methods, and uses merged occupied intervals to find available addresses
without materializing large address sets in Python.
Prefix utilization remains on a cheap utilization-only path for list
views, while Prefix detail views can use a shared usage summary when
both utilization and available IP count are needed. Usable IP bounds now
live on the Prefix model, since the logic depends on Prefix-specific
state such as is_pool.
This also adds host expression indexes for IP Ranges, fixes zero-address
preparation, fixes child IP matching across differing mask lengths,
keeps Prefix hierarchy rebuilding scoped to the existing VRF/global API,
and preserves IPRange.first_available_ip as a cached compatibility
wrapper.
Fixes#21870
Token.generate() used Python's random module (Mersenne Twister PRNG).
Mersenne Twister is not a CSPRNG: observing ~624 outputs from the same
worker process allows full state recovery and prediction of subsequent
outputs. Any token minted in the same worker within that window becomes
predictable, including tokens for privileged accounts.
Fix: replace random.choice with secrets.choice. secrets is backed by
os.urandom() / getrandom() which provides OS-level CSPRNG entropy and
is immune to state-recovery attacks.
The import of the now-unused random module is removed.
Regression tests:
- test_generate_uses_csprng: patches secrets.choice with wraps= to
confirm it is called exactly TOKEN_DEFAULT_LENGTH times per generate().
- test_generate_length_parameter: verifies length= is respected and
output is drawn only from TOKEN_CHARSET.
Ref: SR-001 / VM-317 (internal security review, R1-F07 / R3-F1)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add GET handler to TableConfigEditView that redirects users to home with
a warning if they attempt to access the create form directly without
required object_type and table parameters from a source list view.
Fixes#22237
Introduce declarative GraphQL filter test framework with
`GraphQLFilterTest` and `GraphQLQueryTest` dataclasses. Implement
auto-filter discovery from filter class annotations with per-field-kind
test generators for string, numeric, date, range, and array lookups.
Fixes#15569
Introduce ChoiceSetField as ArrayField subclass for custom field
choices and implement choice_value lookup to filter by value element
only. Update GraphQL filter to use ExtraChoicesLookup with contains and
length options.
Fixes#22324