summaryrefslogtreecommitdiffstats
path: root/modules/systemd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/systemd.nix')
-rw-r--r--modules/systemd.nix49
1 files changed, 49 insertions, 0 deletions
diff --git a/modules/systemd.nix b/modules/systemd.nix
new file mode 100644
index 0000000..20b1d73
--- /dev/null
+++ b/modules/systemd.nix
@@ -0,0 +1,49 @@
+{ config, lib, ... }: let
+ normalUsers =
+ lib.filterAttrs (_: builtins.getAttr "isNormalUser") config.users.users;
+in {
+ options = {
+ tv.systemd.services = lib.mkOption {
+ type = lib.types.attrsOf (lib.types.submodule (self: {
+ options = {
+ operators = lib.mkOption {
+ type =
+ lib.types.listOf
+ (lib.types.enum (builtins.attrNames normalUsers));
+ default = [];
+ };
+ };
+ }));
+ default = {};
+ };
+ };
+ config = {
+ security.polkit.extraConfig = let
+ access =
+ lib.mapAttrs'
+ (name: cfg:
+ lib.nameValuePair "${name}.service"
+ (lib.genAttrs cfg.operators (_: true))
+ )
+ config.tv.systemd.services;
+ in lib.optionalString (access != {}) /* js */ ''
+ polkit.addRule(function () {
+ const access = ${builtins.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;
+ }
+ }
+ }
+ }());
+ '';
+ };
+}