nix-dotfiles/home/programs/gpg/declarative-key-fetcher.nix

108 lines
3.3 KiB
Nix

{ config, pkgs, lib, ... }:
let
cfg = config.programs.gpg;
in
{
# TODO: Create proper descriptions
options = {
programs.gpg.fetch-keys = {
enable = lib.mkEnableOption "auto fetching of gpg keys by fingerprint";
keys = lib.mkOption {
description = "";
default = { };
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
id = lib.mkOption {
description = "";
default = name;
example = "";
type = lib.types.str;
};
keyserver = lib.mkOption {
description = "If marked as null, use config";
default = null;
example = "hkps://keys.openpgp.org";
type = with lib.types; nullOr str;
apply = v: if v == null then "@NULL@" else v;
};
trust = lib.mkOption {
description = "If marked as null, it's mutable";
default = null;
example = 4;
type = with lib.types; nullOr (ints.between 1 5);
};
};
}));
};
};
};
config = {
# TODO: Fix the module so that this unit runs whenever something changes
systemd.user.services.gpg-fetch-keys = let
fetchKeysApplication = let
recvKeysByKeyserver = lib.pipe cfg.fetch-keys.keys [
lib.attrValues
(lib.foldl (acc: key: acc // {
${key.keyserver} = (acc.${key.keyserver} or []) ++ [ key.id ];
}) { })
(lib.mapAttrsToList (keyserver: ids:
if keyserver == "@NULL@"
then "gpg --recv-keys ${lib.escapeShellArgs ids}"
else "gpg --keyserver ${lib.escapeShellArg keyserver} --recv-keys ${lib.escapeShellArgs ids}"))
(lib.concatStringsSep "\n")
];
# Taken from modules/programs/gpg.nix
# Slightly modified in order not to read files
importTrustBashFunctions = let
gpg = "${cfg.package}/bin/gpg";
in ''
function importTrust() {
local keyId trust
keyId="$1"
trust="$2"
{ echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \
| ${gpg} --no-tty --command-fd 0 --edit-key "$keyId"
}
'';
trustKeys = lib.pipe cfg.fetch-keys.keys [
lib.attrValues
(lib.filter (key: key.trust != null))
(map ({ id, trust, ... }: "importTrust '${id}' '${toString trust}'"))
(lib.concatStringsSep "\n")
];
in pkgs.writeShellApplication {
name = "fetch-gpg-keys";
runtimeInputs = [ cfg.package ];
text = lib.concatStringsSep "\n" [
recvKeysByKeyserver
importTrustBashFunctions
trustKeys
];
};
in lib.mkIf cfg.fetch-keys.enable {
Unit = {
Description = "Fetch declaratively listed gpg keys";
Documentation = [ "man:gpg(1)" ];
X-Restart-Triggers = [ "${fetchKeysApplication}" ];
X-SwitchMethod = "restart";
};
Service = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe fetchKeysApplication}";
Environment = [
"GNUPGHOME=${cfg.homedir}"
];
};
};
};
}