2023-01-18 16:13:30 +00:00
|
|
|
with import ./lib;
|
|
|
|
{ config, ... }: let
|
|
|
|
normalUsers = filterAttrs (_: getAttr "isNormalUser") config.users.users;
|
|
|
|
in {
|
|
|
|
options = {
|
|
|
|
tv.systemd.services = mkOption {
|
|
|
|
type = types.attrsOf (types.submodule (self: {
|
|
|
|
options = {
|
|
|
|
operators = mkOption {
|
|
|
|
type = with types; listOf (enum (attrNames normalUsers));
|
|
|
|
default = [];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}));
|
2023-01-18 19:23:18 +00:00
|
|
|
default = {};
|
2023-01-18 16:13:30 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
config = {
|
|
|
|
security.polkit.extraConfig = let
|
|
|
|
access =
|
|
|
|
mapAttrs'
|
|
|
|
(name: cfg:
|
|
|
|
nameValuePair "${name}.service"
|
|
|
|
(genAttrs cfg.operators (const true))
|
|
|
|
)
|
|
|
|
config.tv.systemd.services;
|
|
|
|
in optionalString (access != {}) /* js */ ''
|
|
|
|
polkit.addRule(function () {
|
|
|
|
const access = ${lib.toJSON access};
|
|
|
|
return function (action, subject) {
|
|
|
|
if (action.id === "org.freedesktop.systemd1.manage-units") {
|
|
|
|
const unit = action.lookup("unit");
|
|
|
|
if (
|
|
|
|
(access[unit]||{})[subject.user] ||
|
|
|
|
(
|
|
|
|
unit.includes("@") &&
|
|
|
|
(access[unit.replace(/@[^.]+/, "@")]||{})[subject.user]
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return polkit.Result.YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}());
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
}
|