nixos/os/util/user.nix
deva 61f78061a3
nix magic plus restructuring
(the magic is os/util/user.nix)
2024-07-02 19:43:25 -04:00

308 lines
8.3 KiB
Nix

{
pkgs,
lib,
outputs,
inputs,
config,
...
}: let
userOpts = {
name,
config,
...
}: {
options = with lib; {
allowUnfree = mkOption {
type = with types; bool;
default = true;
description = "Whether or not to allow unfree packages for this user.";
};
username = mkOption {
type = with types; nullOr str;
default = null;
description = "The username of the user, if undefined it uses the name of the attribute set.";
};
homeDirectory = mkOption {
type = with types; nullOr str;
default = null;
description = "The home directory of the user.";
};
description = mkOption {
type = with types; nullOr str;
default = null;
description = "The user's description. It is usually their full name.";
};
uid = mkOption {
type = with types; nullOr int;
default = null;
description = "The user id of the user.";
};
initialPassword = mkOption {
type = with types; nullOr str;
default = null;
description = "The initial password of the user.";
};
hashedPassword = mkOption {
type = with types; nullOr str;
default = null;
description = "The hashed password of the user.";
};
initialHashedPassword = mkOption {
type = with types; nullOr str;
default = null;
description = "The initial hashed password of the user.";
};
normalUser = mkOption {
type = with types; bool;
default = false;
description = "Whether the user is a system user.";
};
desktopEnvironment = mkOption {
type = with types; nullOr (enum ["gnome" "hyprland" "bspwm"]);
default = null;
description = "The desktop environment of the user.";
};
developer = mkOption {
type = with types; bool;
default = false;
description = "Whether or not the user is a developer.";
};
sudoer = mkOption {
type = with types; bool;
default = false;
description = "Whether or not the user has access to sudo.";
};
obs = mkOption {
type = with types; bool;
default = false;
description = "Whether or not the user requires OBS.";
};
authorizedKeys = mkOption {
type = with types; listOf str;
default = [];
description = "List of Authorized SSH Keys for the user.";
};
extraGroups = mkOption {
type = with types; listOf str;
default = [];
description = "Extra groups to put the user in.";
};
packages = mkOption {
type = with types; listOf package;
default = [];
description = "The user's packages.";
};
shell = mkOption {
type = with types; enum ["bash" "zsh"];
default = "zsh";
description = "The user's shell.";
};
};
config = with lib;
mkMerge [
{
shell = mkDefault "zsh";
}
];
};
in {
options = with lib; {
user = mkOption {
type = with types; attrsOf (submodule userOpts);
default = {};
example = {
deva = {
shell = "zsh";
sudoer = true;
developer = true;
desktopEnvironment = "gnome";
obs = true;
name = "Deva Waves";
};
root = {
shell = "zsh";
authorizedKeys = [];
};
};
};
};
config = let
mkIfNoValue = lib.mkOverride 1500;
in {
users.users = lib.mkIf (config.user != null) (lib.attrsets.mapAttrs (name: userConfig: {
uid = (
if userConfig.uid != null
then userConfig.uid
else mkIfNoValue null
);
initialPassword = (
if userConfig.initialPassword != null
then userConfig.initialPassword
else mkIfNoValue null
);
hashedPassword = (
if userConfig.hashedPassword != null
then userConfig.hashedPassword
else mkIfNoValue null
);
initialHashedPassword = (
if userConfig.initialHashedPassword != null
then userConfig.initialHashedPassword
else mkIfNoValue null
);
description = (
if userConfig.description != null
then userConfig.description
else mkIfNoValue "${name}"
);
shell = pkgs.${userConfig.shell};
openssh.authorizedKeys.keys = userConfig.authorizedKeys or [];
isNormalUser =
if userConfig.normalUser
then true
else mkIfNoValue false;
name =
if userConfig.username != null
then userConfig.username
else mkIfNoValue name;
extraGroups =
(
if userConfig.extraGroups != null
then userConfig.extraGroups
else mkIfNoValue []
)
++ (
if userConfig.sudoer
then ["wheel"]
else []
);
})
config.user);
home-manager.users = lib.mkIf (config.user != null) (lib.attrsets.mapAttrs (name: userConfig: {
imports =
[]
++ (
if name != "root"
then [
../services.nix
]
else []
)
++ (
if userConfig.developer
then [
../dev
]
else []
)
++ (
if userConfig.shell == "zsh"
then [
../shell/zsh.nix
]
else []
)
++ (
if userConfig.shell == "bash"
then [
../shell/bash.nix
]
else []
)
++ (
if userConfig.obs
then [
{
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [
wlrobs
];
};
}
]
else []
)
++ (
if userConfig.desktopEnvironment == "gnome"
then [
../desktop/gnome.nix
]
else []
)
++ (
if userConfig.desktopEnvironment == "hyprland"
then [
../desktop/hyprland.nix
]
else []
)
++ (
if userConfig.desktopEnvironment == "bspwm"
then [
../desktop/bspwm.nix
]
else []
);
home = {
username =
if userConfig.username != null
then userConfig.username
else mkIfNoValue name;
homeDirectory =
if userConfig.homeDirectory != null
then userConfig.homeDirectory
else
mkIfNoValue "/home/${(
if userConfig.username != null
then userConfig.username
else name
)}";
extraOutputsToInstall = ["doc" "devdoc"];
packages =
[
inputs.nh.packages.x86_64-linux.default
]
++ userConfig.packages or [];
sessionVariables = {
NIX_AUTO_RUN = "1";
FLAKE = "${config.home-manager.users.${name}.home.homeDirectory}/nix";
};
stateVersion = "24.05";
};
nixpkgs =
if config.home-manager.useGlobalPkgs != true
then {
overlays = [
outputs.overlays.additions
outputs.overlays.modifications
outputs.overlays.unstable-packages
];
config = {
allowUnfree =
if userConfig.allowUnfree != true
then false
else mkIfNoValue true;
};
}
else mkIfNoValue {};
nix.package = lib.mkForce pkgs.unstable.nixVersions.latest;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
manual = {
html.enable = false;
json.enable = false;
manpages.enable = false;
};
programs.home-manager.enable = true;
programs.git.enable = true;
systemd.user.startServices = "sd-switch";
})
config.user);
};
}