Commit Graph

15361 Commits

Author SHA1 Message Date
Brian Tiemann 7f676ea004 Address agent review: format validation, AVIF, animated WebP, cleanup
- Drop 'or PNG' fallback: img.format is always set after a successful
  PillowImage.open() call; UnidentifiedImageError fires before returning None.
- Add extension/content consistency check using PillowImage.MIME to catch
  mismatches like PNG data with a .jpg extension (content-type drift).
- AVIF/JPEG2000: raise a specific ValidationError when save() fails due to
  a missing native codec library, replacing the generic 'unable to process'
  message that was a silent regression from the previous store-as-is behaviour.
- Animated WebP: extend the ImageSequence frame-preservation path to WebP
  (n_frames > 1) alongside GIF.
- Hoist ImageSequence import to module level; split PIL imports onto separate
  lines per ruff isort requirement.
- Tests: use img.n_frames instead of manual seek loop; add animated WebP test;
  add comment explaining why test_clean_rejects_disallowed_extension calls
  clean() directly rather than full_clean().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:14:48 -04:00
Brian Tiemann 0227be7ebe Address code review: correctness fixes and tests for clean() re-encoding
- Move extension allowlist check before PillowImage.open() so SVG/unknown
  formats get a clear error rather than a generic 'unable to process' message.
- Replace hasattr(self.image, 'file') guard with not self.image._committed so
  already-stored images are not unnecessarily re-encoded on every save.
- Replace bare BytesIO assignment with ContentFile so Django's pre_save()
  reliably writes the sanitised content to storage.
- Tighten except clause to (OSError, UnidentifiedImageError, DecompressionBombError).
- Use ImageSequence.Iterator for animated GIF re-encoding to preserve all
  frames; pass duration/loop metadata through.
- Add four model tests covering polyglot stripping, animated GIF frame
  preservation, disallowed extension rejection, and committed-image skip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:14:48 -04:00
Brian Tiemann a0c91099d8 Fix import ordering: move PIL into the third-party block
ruff I001: PIL was in an isolated block between stdlib and django.
Move it into the same third-party block, alphabetically between
django and rest_framework (d < p < r).
2026-06-10 09:14:48 -04:00
Brian Tiemann 78a53cb87c Security: harden ImageAttachment uploads against polyglot XSS
Re-encode uploaded images through Pillow before storage. Pillow's
image.save() produces clean output containing only the image data; any
non-image trailer bytes embedded by a polyglot payload are stripped. An
explicit extension check against IMAGE_ATTACHMENT_IMAGE_FORMATS is also
added so the API path cannot bypass the form-level accept= filter.

Note: X-Content-Type-Options: nosniff and Content-Disposition: attachment
are already provided by the MediaView hardening in #22400 (commit 87c53aa).
This commit provides the complementary upload-time defence.

Pillow is already a required dependency (ImageField uses it for dimension
extraction), so the top-level import adds no new dependency.

Ref: SR-001 / VM-326 (internal security review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:14:39 -04:00
github-actions 34f2ca6f84 Update source translation strings 2026-06-10 06:35:05 +00:00
mburggraf f732a8e878
Fixes #22376: Remove files from request for script action event rules 2026-06-09 13:55:20 -04:00
github-actions c81bd39f7d Update source translation strings 2026-06-09 06:21:09 +00:00
Jeremy Stretch 70391e5a0b
Closes #22392: Deprecate support for Redis 5.x (#22405) 2026-06-08 09:28:31 -07:00
Jeremy Stretch 87c53aaaeb
Fixes #22399: Enforce object permissions for relevant static media (#22400) 2026-06-08 16:05:39 +02:00
bctiemann 6121418f5a
Merge pull request #22391 from netbox-community/22349-minimum-redis-version
Closes #22349: Correct documentation to reflect minimum Redis version of 5.0
2026-06-08 08:40:21 -04:00
github-actions 22d0b22fc9 Update source translation strings 2026-06-05 06:29:27 +00:00
bctiemann f4d95e6e9d
Merge pull request #22384 from netbox-community/15569-add-better-tests-for-graphql-filtering-and-lookup
Closes #15569: Auto-generate GraphQL filter tests for API test cases
2026-06-04 19:17:17 -04:00
Martin Hauser 86ea67d640 fix(extras): Prevent direct access to TableConfig create view
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
2026-06-04 15:58:58 -04:00
Alex Houlton b905e99e63
Closes #22375: Fix VLAN filter_interface_id performance: use UNION instead of OR across M2M joins (#22387) 2026-06-04 15:50:39 -04:00
Jeremy Stretch d592afe56c Closes #22349: Correct documentation to reflect minimum Redis version of 5.0 2026-06-04 14:57:03 -04:00
Jeremy Stretch 553b97464a
Fixes #22388: Pin redis-py to <8.0 (#22389) 2026-06-04 20:55:18 +02:00
Martin Hauser cdde9e98fa
test(api): Add GraphQL nested filter and auto-filter tests
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
2026-06-04 17:45:06 +02:00
github-actions d4d931dd4f Update source translation strings 2026-06-04 06:31:28 +00:00
Martin Hauser 2e50fc3d97
fix(extras): Add choice_value lookup for ChoiceSetField (#22366)
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
2026-06-03 11:06:18 -07:00
Martin Hauser 902aa495dd
Closes #18663: Replace assertions with proper error handling (#22344) 2026-06-03 06:24:10 -05:00
Jeremy Stretch d9a58e6376
Fixes #22357: Remove unused `local_context_data` field from dcim.Module (#22364) 2026-06-03 06:19:46 -05:00
Martin Hauser 62837089b4
Fixes #21895: Fix missing pagination controls for Job Log entries (#22252) 2026-06-03 06:14:38 -05:00
mburggraf 583ab535e8
Fixes #22358: Remove broken and unused function get_0u_devices (#22368) 2026-06-03 13:08:21 +02:00
github-actions 120700688c Update source translation strings 2026-06-03 06:34:32 +00:00
bctiemann c1d69ebae6
Merge pull request #22275 from jniec-js/main
Closes: #22245: Fix OpenAPI request schemas for bulk update endpoints
2026-06-02 21:19:42 -04:00
Josh Niec c3d8b14a3d fix: address pr comments 2026-06-02 19:51:42 -04:00
Josh Niec 56ac8030b8 fix: address pr comments 2026-06-02 19:48:37 -04:00
Josh Niec c264b42abc fix: avoid problem when fields is set to '__all__' 2026-06-02 18:37:24 -04:00
Josh Niec 1597f1bd7d fix: linting 2026-06-02 18:30:10 -04:00
Josh Niec 208dd9b05b fix: address pr comments 2026-06-02 18:28:45 -04:00
Martin Hauser 5561deb1e4 fix(dcim): Refresh cable path for endpoints loaded before tracing
Repair stale `_path` references when an endpoint instance is cabled but
has no path set, as occurs during cable creation before path tracing.
The `path` accessor now refreshes the denormalized FK from the database
in this case, ensuring event payloads include connected endpoints.

Fixes #21338
2026-06-02 16:41:53 -04:00
Martin Hauser 3172e47904
Fixes #22210: Respect filters when rendering IPAM child availability views (#22327)
* fix(ipam): Honor filters for child availability views

Retain the instantiated child FilterSet on ObjectChildrenView and expose
whether child object filters are active. Use this in IPAM child views to
avoid rendering synthetic availability rows when the child queryset has
been filtered.

This ensures Saved Filters and direct filters are respected on
Prefix IP Address, Child Prefix, Aggregate Prefix,
and VLAN Group VLAN tabs.

Fixes #22210

* refactor(ipam): Replace has_active_filters with ChildAvailabilityMixin

Extracts filter detection logic from ObjectChildrenView into a dedicated
ChildAvailabilityMixin. Compares WHERE clause signatures between
filtered and unfiltered querysets instead of inspecting filter
parameters, improving reliability when child querysets are pre-scoped
to parent objects.
2026-06-02 16:30:17 -04:00
bctiemann b1ebd93349
Merge pull request #22365 from netbox-community/22340-token-allowed_ips-list
Fixes #22340: Correct display of allowed IPs for tokens in web UI
2026-06-02 14:21:27 -04:00
Jeremy Stretch 5b08541242 Fixes #22340: Correct display of allowed IPs for tokens in web UI 2026-06-02 12:39:05 -04:00
Jeremy Stretch 839259ccec
Closes #22361: Introduce ArrayAttr UI panel attribute (#22362) 2026-06-02 18:17:02 +02:00
Maksym-Ototiuk fc17d468aa Closes #21666: Add MU fiber connector type 2026-06-02 12:01:26 -04:00
bctiemann 35450a6cb8
Fixes #22251: Re-parent child ModuleBays when a Module is moved to a new bay (#22336) 2026-06-02 08:25:56 -07:00
Jeremy Stretch b55b50b12e
CAP-122: Add GitHub workflow to close new issues missing labels (#22356) 2026-06-02 16:43:52 +02:00
Jeremy Stretch 742f4b4330 Release v4.6.2 2026-06-02 10:11:34 -04:00
Jeremy Stretch 0ea6e334a0 Revert "Fixes #22310: Restore tracked placeholder in project-static/docs to prevent staticfiles warning (#22337)"
This reverts commit a72ab9007e to fix the pre-commit workflow.
2026-06-02 09:44:15 -04:00
bctiemann 5b5e821fbb
Merge pull request #22348 from netbox-community/22180-custom-script-data-source-bypass
Closes #22180: Validate scripts added via a data source
2026-06-02 06:56:46 -04:00
Jason Novinger e44d5d3855 Drop issue reference from data source validation comment
Per AGENTS.md conventions, comments should not reference the current
task or issue number, which rot as the codebase evolves.
2026-06-02 12:03:35 +02:00
Jason Novinger 0ba2fdade0 Fixes #22180: Validate scripts added via a data source
ScriptFileForm only validated uploaded scripts, so a script added by
selecting a data file bypassed validate_script_content. A script that
failed to load was committed as a broken module that showed as missing
and could not be corrected, since re-adding it tripped the file path
uniqueness constraint.

Validate the data file's content in the form's clean() the same way
uploaded files are validated, so a script that cannot be loaded is
rejected before any module is created.
2026-06-02 11:49:59 +02:00
github-actions 03fc20d202 Update source translation strings 2026-06-02 06:31:16 +00:00
Jason Novinger 8c2c6f2349
Fixes #22158: Cache empty config revision state to avoid per-request queries (#22342)
When no ConfigRevision exists, the empty state was never cached, so every
request re-queried core_configrevision. Distinguish a genuine cache miss from
a cached-empty state via a sentinel, seed the empty state on first load, and
only consult the database on a true miss.

Treat the cache as warm only when both 'config' and 'config_version' are
present. A missing 'config_version' (evicted or never written) now re-queries
the database instead of leaving Config.version as None when a ConfigRevision
exists. The no-revision branch writes both keys, so the intentional empty
state remains a cache hit.

The config tests shared a single Redis instance (keyed only by a static
prefix) across parallel test workers, so a no-revision test in one worker
could seed empty config/config_version keys that another worker's test then
read, causing intermittent failures. Use a per-process LocMemCache so the
shared cache keys cannot be contaminated across workers.
2026-06-01 20:18:30 +02:00
Martin Hauser 6724c29ffb
test(core): Clear RQ queues before and after tests (#22320)
Add RQQueueTestMixin to centralize RQ queue cleanup for test cases that
interact with background jobs. The mixin clears all RQ queues in setUp()
and tearDown(), preventing jobs created by one test from leaking into
later unrelated test runs.

Replace duplicate queue cleanup logic in core and netbox tests with the
shared mixin for better maintainability.

Fixes #22318
2026-06-01 10:10:13 -07:00
Martin Hauser bcfeb762e8 refactor(tests): Rename test base classes for clarity
Rename `CablePathTestCase` to `BaseCablePathTestCase` and
`JobRunnerTestCase` to `BaseJobRunnerTestCase` to clearly indicate
their role as abstract base classes rather than concrete test cases.

Fixes #22338
2026-06-01 08:58:21 -04:00
Jason Novinger a72ab9007e
Fixes #22310: Restore tracked placeholder in project-static/docs to prevent staticfiles warning (#22337) 2026-06-01 14:31:51 +02:00
bctiemann bc75706b24
Fixes #22328: Add missing else branch to DynamicMultipleChoiceField.get_bound_field() (#22329) 2026-05-29 09:23:01 -04:00
github-actions fd35c36901 Update source translation strings 2026-05-29 06:24:30 +00:00