From 6bf3ce989d64bc6fece1a0235a83493fcb330346 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Sun, 14 Jun 2026 08:08:16 -0700 Subject: [PATCH] release: archivebox 0.9.35rc33 --- archivebox/core/forms.py | 7 +++- archivebox/core/views.py | 3 +- archivebox/tests/test_ui_add_view.py | 55 ++++++++++++++++++++++++++++ etc/package.json | 2 +- pyproject.toml | 8 ++-- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/archivebox/core/forms.py b/archivebox/core/forms.py index 2cc025ae..94f973e6 100644 --- a/archivebox/core/forms.py +++ b/archivebox/core/forms.py @@ -9,7 +9,7 @@ from archivebox.misc.util import URL_REGEX, find_all_urls, parse_filesize_to_byt from archivebox.base_models.admin import KeyValueWidget from archivebox.crawls.schedule_util import validate_schedule from archivebox.config.common import get_config, parse_delete_after -from archivebox.core.permissions import PERMISSIONS_CHOICES, PERMISSIONS_PUBLIC, filter_personas_by_permissions, is_admin_user +from archivebox.core.permissions import PERMISSIONS_CHOICES, PERMISSIONS_PUBLIC, filter_personas_by_permissions from archivebox.core.widgets import TagEditorWidget, URLFiltersWidget from archivebox.plugins.discovery import get_plugins from archivebox.plugins.forms import ( @@ -299,7 +299,10 @@ class AddLinkForm(PluginConfigFormMixin, forms.Form): def __init__(self, *args, **kwargs): self.request = kwargs.pop("request", None) - self.can_override_crawl_config = bool(self.request and is_admin_user(self.request)) + self.can_override_crawl_config = False + if self.request is not None: + user = self.request.user + self.can_override_crawl_config = bool(user.is_authenticated and user.is_active and user.is_superuser) super().__init__(*args, **kwargs) default_persona = Persona.get_or_create_default() diff --git a/archivebox/core/views.py b/archivebox/core/views.py index bb9bef8e..d5f89cdf 100644 --- a/archivebox/core/views.py +++ b/archivebox/core/views.py @@ -1405,7 +1405,8 @@ class AddView(UserPassesTestMixin, FormView): return get_request_config(self.request).PUBLIC_ADD_VIEW or self.request.user.is_authenticated def _can_override_crawl_config(self) -> bool: - return is_admin_user(self.request) + user = self.request.user + return bool(user.is_authenticated and user.is_active and user.is_superuser) def _get_custom_config_overrides(self, form: AddLinkForm) -> dict: custom_config = form.cleaned_data.get("config") or {} diff --git a/archivebox/tests/test_ui_add_view.py b/archivebox/tests/test_ui_add_view.py index 73bda32f..95632786 100644 --- a/archivebox/tests/test_ui_add_view.py +++ b/archivebox/tests/test_ui_add_view.py @@ -99,6 +99,61 @@ def test_add_view_admin_renders_plugin_config_grid(client, admin_user, monkeypat assert b"plugin_config__wget__WGET_ENABLED" not in response.content +def test_add_view_staff_user_cannot_override_raw_or_plugin_config(client): + staff_user = User.objects.create_user( + username="addviewstaff", + email="addviewstaff@test.com", + password="testpassword", + is_staff=True, + is_superuser=False, + ) + client.force_login(staff_user) + + response = client.get(reverse("add"), HTTP_HOST=ADMIN_HOST) + assert response.status_code == 200 + assert response.context["can_override_crawl_config"] is False + assert response.context["form"].plugin_groups == [] + assert b"plugin_config__wget__WGET_TIMEOUT" not in response.content + assert b"Custom config overrides" not in response.content + + response = client.post( + reverse("add"), + data={ + "url": "https://example.com/staff-config", + "tag": "", + "depth": "0", + "max_urls": "0", + "crawl_max_size": "0", + "crawl_timeout": "0", + "timeout": "60", + "snapshot_max_size": "0", + "delete_after": "0", + "crawl_max_concurrent_snapshots": "1", + "url_filters_allowlist": "", + "url_filters_denylist": "", + "notes": "", + "schedule": "daily", + "persona": "Default", + "permissions": "public", + "start_paused": "on", + "main_plugins": ["wget"], + "plugin_config__wget__WGET_TIMEOUT": "77", + "config": '{"WGET_TIMEOUT": 77, "YTDLP_ARGS_EXTRA": ["--exec", "touch /tmp/owned"]}', + }, + HTTP_HOST=ADMIN_HOST, + ) + + assert response.status_code == 302 + crawl = Crawl.objects.order_by("-created_at").first() + assert crawl is not None + assert crawl.created_by == staff_user + assert crawl.status == Crawl.StatusChoices.QUEUED + assert crawl.schedule is None + assert crawl.config.get("PLUGINS", "") == "" + assert crawl.config.get("WGET_TIMEOUT") != 77 + assert crawl.config.get("YTDLP_ARGS_EXTRA") != ["--exec", "touch /tmp/owned"] + + def test_add_view_embeds_selected_persona_config_for_ui_hydration(client, admin_user, monkeypatch): monkeypatch.setenv("PUBLIC_ADD_VIEW", "true") client.force_login(admin_user) diff --git a/etc/package.json b/etc/package.json index 15ec9a17..33c729cd 100644 --- a/etc/package.json +++ b/etc/package.json @@ -1,6 +1,6 @@ { "name": "archivebox", - "version": "0.9.35rc32", + "version": "0.9.35rc33", "repository": "github:ArchiveBox/ArchiveBox", "license": "MIT", "dependencies": { diff --git a/pyproject.toml b/pyproject.toml index bde5a1d7..2bdb6dbd 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "archivebox" -version = "0.9.35rc32" +version = "0.9.35rc33" requires-python = ">=3.13" description = "Self-hosted internet archiving solution." authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}] @@ -79,9 +79,9 @@ dependencies = [ ### Extractor dependencies (optional binaries detected at runtime via shutil.which) ### Binary/Package Management "abxbus==2.5.10", # EventBus API - "abxpkg>=1.11.213", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm - "abx-plugins>=1.11.217", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring - "abx-dl>=1.11.217", # shared ArchiveBox downloader package with blocking install preflight + "abxpkg>=1.11.214", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm + "abx-plugins>=1.11.218", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring + "abx-dl>=1.11.218", # shared ArchiveBox downloader package with blocking install preflight ### UUID7 backport for Python <3.14 "uuid7>=0.1.0; python_version < '3.14'", # provides the uuid_extensions module on Python 3.13 ]