Class StaticThemeInstaller
The installer enforces security guards against ZipSlip, oversized extractions, excessive entry counts, and compression-ratio bombs. Successful extractions are promoted into the active themes directory via an atomic directory rename so partial installs never become visible to readers.
Lifecycle:
- Stream the archive into a staging directory under
themes/.staging-<uuid>. - Validate the embedded
theme.ymlviaThemeManifest. - If a theme with the same name exists, rename it to an
.attic-backup so a failed promotion can roll back. The attic'slastModifiedTimeis reset to "now" right after the rename so thetheme.upload.attic.retention.dayswindow starts from the install moment, not the original theme directory's age. - Atomically rename the staging directory to
themes/<name>and reload theThemeRegistry. - On success the attic backup is retained per
theme.upload.attic.retention.days(default 7 days) and aged out bycleanupOldAtticDirs(Path); it is no longer eagerly deleted.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classRaised on any failure during ZIP validation or extraction. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected org.codelibs.fess.mylasta.direction.FessConfigInjected Fess configuration used to resolve limits and the themes directory.protected ThemeRegistryInjected theme registry reloaded after successful install/delete. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidRemoves the static-theme directory atomically.voidinit()Wire configuration keys fromFessConfigand sweep JVM-crash orphan staging directories at container startup.voidinstallZip(InputStream zipStream) Installs a theme from the supplied ZIP stream.protected voidAtomically movessourcetodest.
-
Field Details
-
fessConfig
protected org.codelibs.fess.mylasta.direction.FessConfig fessConfigInjected Fess configuration used to resolve limits and the themes directory. -
themeRegistry
Injected theme registry reloaded after successful install/delete.
-
-
Constructor Details
-
StaticThemeInstaller
public StaticThemeInstaller()Default constructor. Configured limits are read fromFessConfigduringinit(); falls back to built-in defaults when DI is absent.
-
-
Method Details
-
init
@PostConstruct public void init()Wire configuration keys fromFessConfigand sweep JVM-crash orphan staging directories at container startup.Hardcoded field values above serve as defaults when
FessConfigis absent (e.g. unit tests where DI is not set up). -
installZip
Installs a theme from the supplied ZIP stream.- Parameters:
zipStream- the archive content; the caller retains ownership of closing the underlying stream- Throws:
StaticThemeInstaller.InstallException- if validation, extraction, or promotion fails
-
delete
Removes the static-theme directory atomically.Refuses when (a) the name fails the spec §4.2 regex (
^[a-z0-9][a-z0-9_-]{0,63}$), (b) the theme is the currently active default (per the configured probe orThemeRegistry.resolveActiveTheme(String)), or (c) the directory does not exist under the themes root.Successful deletion atomically renames the directory to
themes/.attic-<name>-<timestamp>/— preserving the §4.4 7-day retention semantics — and reloads theThemeRegistry.- Parameters:
name- the theme directory name; must match^[a-z0-9][a-z0-9_-]{0,63}$- Throws:
StaticThemeInstaller.InstallException- on validation, lookup, or rename failure
-
moveDir
Atomically movessourcetodest. Falls back to a plain replacing move on filesystems that do not supportATOMIC_MOVE.Exposed as an instance method (rather than a
statichelper) so unit tests can subclass and inject failure modes to exercise the promotion/rollback paths ininstallZip(InputStream).- Parameters:
source- path to movedest- destination path- Throws:
IOException- if the move fails on the underlying filesystem
-