From e6915e8abdc62e01cdf7ab370fe7bcea467794b4 Mon Sep 17 00:00:00 2001 From: alexion Date: Mon, 5 Oct 2026 00:04:07 -0400 Subject: [PATCH] fix(nixos): validate route protocol fields --- configs/nixos/registry/route.nix | 112 +++++++++++++++++-------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/configs/nixos/registry/route.nix b/configs/nixos/registry/route.nix index 397a705..3cfae5e 100644 --- a/configs/nixos/registry/route.nix +++ b/configs/nixos/registry/route.nix @@ -1,49 +1,4 @@ { lib, util, ... }: -let - # NOLINT(let_order) - routeType = - protocols: options: - lib.types.submodule { - options = { - domain = lib.mkOption { - type = lib.types.str; - example = "files.alexion.dev"; - description = "Public domain for this route."; - }; - - protocol = lib.mkOption { - type = lib.types.enum protocols; - description = "Public protocol for this route."; - }; - } - // options; - }; - - webRoute = - routeType - [ - "http" - "https" - ] - { - port = lib.mkOption { - type = lib.types.port; - example = 3923; - description = "HTTP backend port for this route."; - }; - }; - - udpRoute = routeType [ "udp" ] { - ports = lib.mkOption { - type = lib.types.nonEmptyListOf lib.types.port; - example = [ - 2456 - 2457 - ]; - description = "UDP ports for this route."; - }; - }; -in { checks = [ { @@ -54,16 +9,69 @@ in assertion = entries: util.registry.predicates.uniqueValue (entry: entry.value) ( - lib.concatMap (entry: map (port: entry // { value = port; }) entry.value.ports) ( - lib.filter (entry: entry.value.protocol == "udp") entries - ) + lib.concatMap (entry: map (port: entry // { value = port; }) entry.value.ports) entries ); message = "Route UDP ports must be unique."; } + { + assertion = + entries: + lib.all ( + entry: + let + route = entry.value; + in + !lib.elem route.protocol [ + "http" + "https" + ] + || (route.port != null && route.ports == [ ]) + ) entries; + message = "HTTP and HTTPS routes must set port and not ports."; + } + { + assertion = + entries: + lib.all ( + entry: entry.value.protocol != "udp" || (entry.value.port == null && entry.value.ports != [ ]) + ) entries; + message = "UDP routes must set ports and not port."; + } ]; - type = lib.types.oneOf [ - webRoute - udpRoute - ]; + type = lib.types.submodule { + options = { + domain = lib.mkOption { + type = lib.types.str; + example = "files.alexion.dev"; + description = "Public domain for this route."; + }; + + protocol = lib.mkOption { + type = lib.types.enum [ + "http" + "https" + "udp" + ]; + description = "Public protocol for this route."; + }; + + port = lib.mkOption { + type = lib.types.nullOr lib.types.port; + default = null; + example = 3923; + description = "HTTP backend port for an HTTP or HTTPS route."; + }; + + ports = lib.mkOption { + type = lib.types.listOf lib.types.port; + default = [ ]; + example = [ + 2456 + 2457 + ]; + description = "UDP ports for a UDP route."; + }; + }; + }; }