{ config, lib, pkgs, ... }: let cfg = config.vhack.users; mkUser = { name, hashedPassword, uid, sshKey, groups, enableDeprecatedPlugdev, }: { inherit name; value = { inherit name uid hashedPassword; isNormalUser = true; createHome = true; home = "/home/${name}"; extraGroups = groups ++ lib.optional enableDeprecatedPlugdev "plugdev"; openssh.authorizedKeys.keys = [ sshKey ]; }; }; extraUsers = lib.listToAttrs ( builtins.map mkUser cfg.users ); in { options.vhack.users = { enable = lib.mkEnableOption "user setup"; users = lib.mkOption { type = lib.types.listOf (lib.types.submodule { options = { name = lib.mkOption { type = lib.types.str; description = "User name"; }; groups = lib.mkOption { type = lib.types.listOf lib.types.str; default = ["wheel"]; description = "The groups the user should be part of"; }; # Although deprecated, this helps with old udev rules, that still use this group. # TODO: Try to find a way to remove this option (i.e. set it always to false). enableDeprecatedPlugdev = lib.mkEnableOption "the deprecated plugdev group for the user"; hashedPassword = lib.mkOption { type = lib.types.str; description = "Hashed user password."; }; sshKey = lib.mkOption { type = lib.types.str; description = "public ssh key, for ssh access."; }; uid = lib.mkOption { type = lib.types.int; description = "UNIQUE user id, ideally greater than 1000."; }; }; }); description = "Users"; }; }; config = lib.mkIf cfg.enable { programs.fish = { enable = true; useBabelfish = true; }; users = { mutableUsers = false; defaultUserShell = config.programs.fish.package; users = { root = { hashedPassword = lib.mkForce null; # to lock root openssh.authorizedKeys.keys = lib.mkForce []; }; } // extraUsers; }; }; }