{ config, lib, ... }: { options.snowflake.user = { enable = lib.mkEnableOption "Enable user configuration"; users = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { isNormalUser = lib.mkOption { type = lib.types.bool; default = true; description = "Whether the user is a normal user."; }; shell = lib.mkOption { type = lib.types.package; description = "the shell package for the user."; }; description = lib.mkOption { type = lib.types.str; description = "full name for the user."; }; extraGroups = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "system groups to add this user to."; }; initialHashedPassword = lib.mkOption { type = lib.types.str; description = "hashed password for the user, can be generated using `mkpasswd -m bcrypt -R 10`"; }; authorizedKeys = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "SSH authorized keys for the user."; }; }; }); }; }; config = lib.mkIf config.snowflake.user.enable { # make users immutable users.mutableUsers = false; # Configure the user account. # NOTE: hashedPasswordFile has an issue. If the auth method is changed from `hashedPassword` # to `hashedPasswordFile`, /etc/shadow gets messed up and login does not work. To fix this # we need to remove all the users' entries from /etc/shadow and run nixos-rebuild. Seems to be # a one-time thing. # ref: https://github.com/NixOS/nixpkgs/issues/99433 users.users = lib.mapAttrs (username: userCfg: { isNormalUser = userCfg.isNormalUser; shell = userCfg.shell; description = userCfg.description; extraGroups = userCfg.extraGroups; initialHashedPassword = userCfg.initialHashedPassword; openssh.authorizedKeys.keys = userCfg.authorizedKeys; }) config.snowflake.user.users; }; }