A theme change compiled Bootswatch with libsass (34 MB, upstream
deprecated) into two tracked files, which updates, rollbacks and new
Docker containers then reset. The 27 themes now ship as
static/css/themes/<theme>.min.css, built by "manage.py build_themes";
the Settings page only saves the theme name and every page links that
file (zephyr when no settings are in context, as on the 500 page).
libsass moves to dev/requirements.txt; a test checks that each shipped
file is its theme compiled from dev/scss. The "Theme SASS Path" setting
is removed, and the theme default "flaty", a typo that never applied,
becomes zephyr, the theme those installs showed. The update and
rollback steps restore an older version's rewritten theme files only
where they are modified.
nginx serves STATIC_ROOT (staticfiles/) since collectstatic moved there,
but the theme view wrote only static/css/wvc-main.min.css, so a new theme
showed up only after the next collectstatic. The view now also writes the
collected copy when collectstatic has run; the source copy stays so a
later collectstatic keeps the theme.
The settings page lists the themes of SASS_DIR and writes wvc-main.scss
into it when the theme changes; the value could be any path, so a
superuser could make the app list and write files anywhere it may
(CodeQL py/path-injection).
SASS_DIR is now accepted only if it resolves to an existing directory
inside the project (the default is dev/scss). A stored value outside it
is not used: the page shows an error and offers no themes, so nothing
is written. Installations that keep their SCSS outside the project
need to move it under it.
The tests fail on the previous code for an absolute path, "../",
a path climbing out and a missing directory, and for a stored value
outside the project.
The settings page took the posted theme name as it came and wrote it
into the @import lines of wvc-main.scss and the compiled CSS: a name
with "../" or a quote imported files outside the themes directory
(CodeQL py/path-injection; the page is for superusers).
The name must now be one of the directories in SASS_DIR/wvc-themes, the
list the page already offers; anything else is refused with a message
and nothing is written. themes_list is empty when SASS_DIR has no
themes, so every name is refused then.
Checked with the real dev/scss: flatly is applied and compiled as
before, "../../etc" is refused and leaves the CSS alone. The test fails
on the previous code.
Super-linter ran from the unpinned :latest image and, because of
branches-ignore: [master], never on pull requests to master. Ruff now
checks syntax errors and pyflakes rules (E9, F) on every push and PR.
Fixes the existing findings: unused imports and variables, an unused
duplicate import in instances/tests.py, and the star import in
accounts/views.py. settings-dev.py keeps its star import of the base
settings.
- Computes API: mark password as write_only in ComputeSerializer, restrict ComputeViewSet and architectures to IsAdminUser.
- Instances API: enforce user ownership tenant isolation in InstanceViewSet.list, restrict MigrateViewSet and CreateInstanceViewSet to IsAdminUser, require IsAdminUser for mutating FlavorViewSet.
- Storage, Network, and Interface APIs: restrict StorageViewSet, VolumeViewSet, NetworkViewSet, InterfaceViewSet to IsAdminUser.
- AppSettings & NWFilters: protect appsettings and nwfilter views with @superuser_only (403 Forbidden for non-superusers).
- noVNC Console: sign tokens with TimestampSigner (salt='console.novnc', max_age=600), verify signature and user authorization in novncd with backward-compatible fallback for debug/test mode.
- Accounts: avoid hardcoded default admin password; generate cryptographically secure random password unless ADMIN_PASSWORD is set (preserve 'admin' in test runner).
- gstfsd daemon: bind to 127.0.0.1 by default instead of 0.0.0.0.
- Tests: added comprehensive test coverage for API security, token expiration/rejection, and view permissions (132 tests passing).