olivetin-3k: init at 3000.11.3, olivetin: update gen hash, refactor (#498611)

This commit is contained in:
Sandro
2026-03-20 21:05:58 +00:00
committed by GitHub
6 changed files with 296 additions and 127 deletions
+11 -1
View File
@@ -17,7 +17,17 @@ in
options.services.olivetin = {
enable = lib.mkEnableOption "OliveTin";
package = lib.mkPackageOption pkgs "olivetin" { };
package = lib.mkOption {
type = lib.types.package;
description = "The olivetin package to use.";
default =
if lib.versionAtLeast config.system.stateVersion "26.05" then pkgs.olivetin-3k else pkgs.olivetin;
defaultText = lib.literalExpression ''
if lib.versionAtLeast config.system.stateVersion "26.05"
then pkgs.olivetin-3k
else pkgs.olivetin
'';
};
user = lib.mkOption {
type = lib.types.str;
+13 -3
View File
@@ -1,4 +1,4 @@
{ lib, ... }:
{ config, lib, ... }:
{
name = "olivetin";
@@ -41,16 +41,26 @@
testScript = ''
import json
import shlex
machine.wait_for_unit("olivetin.service")
machine.wait_for_open_port(8000)
response = json.loads(machine.succeed("curl http://localhost:8000/api/StartActionByGetAndWait/hello_world"))
def start_action(action):
if "${config.nodes.machine.services.olivetin.package.releaseSeries}" == "2k":
cmd = f"curl http://localhost:8000/api/StartActionByGetAndWait/{action}"
else:
req = {"actionId": action}
cmd = f"curl -H 'Content-Type: application/json' http://localhost:8000/api/olivetin.api.v1.OliveTinApiService/StartActionAndWait -d {shlex.quote(json.dumps(req))}"
return json.loads(machine.succeed(cmd))
response = start_action("hello_world")
assert response["logEntry"]["exitCode"] == 0
assert response["logEntry"]["output"] == "Hello World!"
assert machine.succeed("cat /tmp/result") == "Hello World!"
response = json.loads(machine.succeed("curl http://localhost:8000/api/StartActionByGetAndWait/secret"))
response = start_action("secret")
assert response["logEntry"]["exitCode"] == 0
assert machine.succeed("cat /tmp/result2") == "secret"
'';
+141
View File
@@ -0,0 +1,141 @@
{
lib,
fetchFromGitHub,
buildGoModule,
stdenvNoCC,
writableTmpDirAsHomeHook,
buf,
protoc-gen-go,
protoc-gen-go-grpc,
grpc-gateway,
buildNpmPackage,
installShellFiles,
versionCheckHook,
nixosTests,
}:
buildGoModule (finalAttrs: {
pname = "olivetin";
version = "3000.11.3";
src = fetchFromGitHub {
owner = "OliveTin";
repo = "OliveTin";
tag = finalAttrs.version;
hash = "sha256-GSCqtekFj0c2TPSygRiUAfSMQAyPbfuR0dxAGQ/Rghw=";
};
modRoot = "service";
vendorHash = "sha256-iH9tgw4KSER/xIPOIontSQLWrI4ORayRjyHsT1HU0m8=";
subPackages = [ "." ];
ldflags = [
"-s"
"-w"
"-X main.version=${finalAttrs.version}"
];
__darwinAllowLocalNetworking = true;
gen = stdenvNoCC.mkDerivation {
pname = "olivetin-gen";
inherit (finalAttrs) version src;
nativeBuildInputs = [
writableTmpDirAsHomeHook
buf
protoc-gen-go
protoc-gen-go-grpc
grpc-gateway
];
buildPhase = ''
runHook preBuild
pushd proto
buf generate
popd
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r service/gen $out
runHook postInstall
'';
postFixup = ''
find $out -type f -name '*.go' -exec \
sed -i -E 's|//.*protoc-gen-go(-grpc)? +v.*$||' {} +
'';
outputHashMode = "recursive";
outputHash = "sha256-SaGHxawFw55zI37psqI9kdaR8DLnx4iV2XZdomr28b8=";
};
webui = buildNpmPackage {
pname = "olivetin-webui";
inherit (finalAttrs) version src;
npmDepsHash = "sha256-vrvwy96wtXxt0JJDs8YG0Lm3kpVRoJ2Qmu8nlggH6qc=";
sourceRoot = "${finalAttrs.src.name}/frontend";
buildPhase = ''
runHook preBuild
make build
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r dist $out
runHook postInstall
'';
};
nativeBuildInputs = [ installShellFiles ];
preBuild = ''
ln -s ${finalAttrs.gen} gen
substituteInPlace internal/config/config.go \
--replace-fail 'config.WebUIDir = "./webui"' 'config.WebUIDir = "${finalAttrs.webui}"'
'';
postInstall = ''
installManPage ../var/manpage/OliveTin.1.gz
'';
nativeInstallCheckInputs = [ versionCheckHook ];
versionCheckProgramArg = "-version";
doInstallCheck = true;
passthru = {
tests.olivetin = nixosTests.olivetin.extendNixOS {
module = {
services.olivetin.package = finalAttrs.finalPackage;
};
};
releaseSeries = "3k";
updateScript = ./update-3k.sh;
};
meta = {
description = "Gives safe and simple access to predefined shell commands from a web interface";
homepage = "https://www.olivetin.app/";
downloadPage = "https://github.com/OliveTin/OliveTin";
changelog = "https://github.com/OliveTin/OliveTin/releases/tag/${finalAttrs.version}";
license = lib.licenses.agpl3Only;
maintainers = with lib.maintainers; [ defelo ];
mainProgram = "OliveTin";
};
})
+120 -123
View File
@@ -14,145 +14,142 @@
nixosTests,
}:
buildGoModule (
finalAttrs:
buildGoModule (finalAttrs: {
pname = "olivetin";
version = "2025.11.25";
let
gen = stdenvNoCC.mkDerivation {
pname = "olivetin-gen";
inherit (finalAttrs) version src;
src = fetchFromGitHub {
owner = "OliveTin";
repo = "OliveTin";
tag = finalAttrs.version;
hash = "sha256-HQLInEVXowWpDaSW/4bduUMdYsvQ0Rju1Rl2l9jupYA=";
};
nativeBuildInputs = [
writableTmpDirAsHomeHook
buf
protoc-gen-go
protoc-gen-go-grpc
grpc-gateway
];
patches = [ ./update-go-sum.patch ];
buildPhase = ''
runHook preBuild
modRoot = "service";
pushd proto
buf generate
popd
vendorHash = "sha256-xSroaS6fwHrQ0s09uD3bkBZWWxbIndiOGL2JPvKzC6E=";
runHook postBuild
'';
ldflags = [
"-s"
"-w"
"-X main.version=${finalAttrs.version}"
];
installPhase = ''
runHook preInstall
__darwinAllowLocalNetworking = true;
cp -r service/gen $out
gen = stdenvNoCC.mkDerivation {
pname = "olivetin-gen";
inherit (finalAttrs) version src;
runHook postInstall
'';
postFixup = ''
find $out -type f -name '*.go' -exec \
sed -i -E 's|//.*protoc-gen-go(-grpc)? +v.*$||' {} +
'';
outputHashMode = "recursive";
outputHash = "sha256-wHqXsSV18mF/CfLQ0S4rGtT3QRcLnneYXAa8nXZaHpQ=";
};
webui = buildNpmPackage {
pname = "olivetin-webui";
inherit (finalAttrs) version src;
npmDepsHash = "sha256-a1BBNlGusdMlmDXgclGqkO8AywSd4DTQKkuBVzuzAfE=";
sourceRoot = "${finalAttrs.src.name}/webui.dev";
buildPhase = ''
runHook preBuild
npx parcel build --public-url "."
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r dist $out
cp -r *.png $out
runHook postInstall
'';
};
in
{
pname = "olivetin";
version = "2025.11.25";
src = fetchFromGitHub {
owner = "OliveTin";
repo = "OliveTin";
tag = finalAttrs.version;
hash = "sha256-HQLInEVXowWpDaSW/4bduUMdYsvQ0Rju1Rl2l9jupYA=";
};
patches = [ ./update-go-sum.patch ];
modRoot = "service";
vendorHash = "sha256-xSroaS6fwHrQ0s09uD3bkBZWWxbIndiOGL2JPvKzC6E=";
ldflags = [
"-s"
"-w"
"-X main.version=${finalAttrs.version}"
nativeBuildInputs = [
writableTmpDirAsHomeHook
buf
protoc-gen-go
protoc-gen-go-grpc
grpc-gateway
];
__darwinAllowLocalNetworking = true;
buildPhase = ''
runHook preBuild
nativeBuildInputs = [ installShellFiles ];
pushd proto
buf generate
popd
preBuild = ''
ln -s ${gen} gen
substituteInPlace internal/config/config.go \
--replace-fail 'config.WebUIDir = "./webui"' 'config.WebUIDir = "${webui}"'
substituteInPlace internal/httpservers/webuiServer_test.go \
--replace-fail '"../webui/"' '"${webui}"'
runHook postBuild
'';
postInstall = ''
installManPage ../var/manpage/OliveTin.1.gz
installPhase = ''
runHook preInstall
cp -r service/gen $out
runHook postInstall
'';
nativeInstallCheckInputs = [ versionCheckHook ];
versionCheckProgram = "${placeholder "out"}/bin/OliveTin";
versionCheckProgramArg = "-version";
doInstallCheck = true;
postFixup = ''
find $out -type f -name '*.go' -exec \
sed -i -E 's|//.*protoc-gen-go(-grpc)? +v.*$||' {} +
'';
passthru = {
inherit gen webui;
tests = { inherit (nixosTests) olivetin; };
updateScript = ./update.sh;
};
outputHashMode = "recursive";
outputHash = "sha256-fTsJE9ymtJ0TU2OhXLE+XfEOckFMG7IPi0IHHAmN84s=";
};
meta = {
description = "Gives safe and simple access to predefined shell commands from a web interface";
homepage = "https://www.olivetin.app/";
downloadPage = "https://github.com/OliveTin/OliveTin";
changelog = "https://github.com/OliveTin/OliveTin/releases/tag/${finalAttrs.version}";
license = lib.licenses.agpl3Only;
maintainers = with lib.maintainers; [ defelo ];
mainProgram = "OliveTin";
knownVulnerabilities = [
"CVE-2026-27626: OS Command Injection via password argument type and webhook JSON extraction bypasses shell safety checks"
"CVE-2026-28342: Unauthenticated Denial of Service via Memory Exhaustion in PasswordHash API Endpoint"
"CVE-2026-28789: Unauthenticated DoS via concurrent map writes in OAuth2 state handling"
"CVE-2026-28790: Unauthenticated Action Termination via KillAction When Guests Must Login"
"CVE-2026-30223: JWT Audience Validation Bypass in Local Key and HMAC Modes"
"CVE-2026-30224: Session Fixation - Logout Fails to Invalidate Server-Side Session"
"CVE-2026-30225: RestartAction always runs actions as guest"
"CVE-2026-30233: View permission not being checked when returning dashboards"
"CVE-2026-31817: Unsafe parsing of UniqueTrackingId can be used to write files"
];
webui = buildNpmPackage {
pname = "olivetin-webui";
inherit (finalAttrs) version src;
npmDepsHash = "sha256-a1BBNlGusdMlmDXgclGqkO8AywSd4DTQKkuBVzuzAfE=";
sourceRoot = "${finalAttrs.src.name}/webui.dev";
buildPhase = ''
runHook preBuild
npx parcel build --public-url "."
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r dist $out
cp -r *.png $out
runHook postInstall
'';
};
nativeBuildInputs = [ installShellFiles ];
preBuild = ''
ln -s ${finalAttrs.gen} gen
substituteInPlace internal/config/config.go \
--replace-fail 'config.WebUIDir = "./webui"' 'config.WebUIDir = "${finalAttrs.webui}"'
substituteInPlace internal/httpservers/webuiServer_test.go \
--replace-fail '"../webui/"' '"${finalAttrs.webui}"'
'';
postInstall = ''
installManPage ../var/manpage/OliveTin.1.gz
'';
nativeInstallCheckInputs = [ versionCheckHook ];
versionCheckProgramArg = "-version";
doInstallCheck = true;
passthru = {
tests.olivetin = nixosTests.olivetin.extendNixOS {
module = {
services.olivetin.package = finalAttrs.finalPackage;
};
};
}
)
releaseSeries = "2k";
updateScript = ./update.sh;
};
meta = {
description = "Gives safe and simple access to predefined shell commands from a web interface";
homepage = "https://www.olivetin.app/";
downloadPage = "https://github.com/OliveTin/OliveTin";
changelog = "https://github.com/OliveTin/OliveTin/releases/tag/${finalAttrs.version}";
license = lib.licenses.agpl3Only;
maintainers = with lib.maintainers; [ defelo ];
mainProgram = "OliveTin";
knownVulnerabilities = [
"CVE-2026-27626: OS Command Injection via password argument type and webhook JSON extraction bypasses shell safety checks"
"CVE-2026-28342: Unauthenticated Denial of Service via Memory Exhaustion in PasswordHash API Endpoint"
"CVE-2026-28789: Unauthenticated DoS via concurrent map writes in OAuth2 state handling"
"CVE-2026-28790: Unauthenticated Action Termination via KillAction When Guests Must Login"
"CVE-2026-30223: JWT Audience Validation Bypass in Local Key and HMAC Modes"
"CVE-2026-30224: Session Fixation - Logout Fails to Invalidate Server-Side Session"
"CVE-2026-30225: RestartAction always runs actions as guest"
"CVE-2026-30233: View permission not being checked when returning dashboards"
"CVE-2026-31817: Unsafe parsing of UniqueTrackingId can be used to write files"
];
};
})
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p nix-update common-updater-scripts
set -euo pipefail
nix-update olivetin-3k --src-only --override-filename
update-source-version olivetin-3k --source-key=gen --ignore-same-version
update-source-version olivetin-3k --source-key=webui.npmDeps --ignore-same-version
update-source-version olivetin-3k --source-key=goModules --ignore-same-version
+2
View File
@@ -12416,6 +12416,8 @@ with pkgs;
radicle-node-unstable = callPackage ../by-name/ra/radicle-node/unstable.nix { };
olivetin-3k = callPackage ../by-name/ol/olivetin/3k.nix { };
newlib-nano = newlib.override {
nanoizeNewlib = true;
};