From 47802f7450760eabfb86ea2aa9eaa6b0bc70cdf4 Mon Sep 17 00:00:00 2001
From: Manuel Thalmann <m@nuth.ch>
Date: Tue, 7 May 2024 22:02:12 +0200
Subject: [PATCH] Simplify configuring users

---
 flake.nix                |  1 +
 lib/configuration.nix    |  3 +++
 lib/modules/my-users.nix | 50 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)
 create mode 100644 lib/modules/my-users.nix

diff --git a/flake.nix b/flake.nix
index a018486..abf573a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -50,6 +50,7 @@
             keyMap = "us";
             keyboardLayout = "us";
             localeSettings = { };
+            users = { };
           };
           systems = {
             nixos.config = { ... }: {
diff --git a/lib/configuration.nix b/lib/configuration.nix
index 8711053..78c8b6d 100644
--- a/lib/configuration.nix
+++ b/lib/configuration.nix
@@ -2,6 +2,7 @@
   imports = [
     ./modules/custom-build-vm.nix
     ./modules/custom-sops-nix.nix
+    ./modules/my-users.nix
   ];
 
   config = {
@@ -23,6 +24,8 @@
         vmVariantWithBootLoader = vmConfig;
       };
 
+    users.myUsers = machineConfig.users;
+
     # Networking
     networking.hostName = machineConfig.name;
 
diff --git a/lib/modules/my-users.nix b/lib/modules/my-users.nix
new file mode 100644
index 0000000..6a295cf
--- /dev/null
+++ b/lib/modules/my-users.nix
@@ -0,0 +1,50 @@
+{ config, lib, ... }:
+let
+  userType = lib.types.submodule {
+    options = {
+      fullName = lib.mkOption {
+        type = lib.types.nullOr lib.types.str;
+        description = lib.mdDoc "The full name of the user.";
+        default = null;
+      };
+
+      defaultShell = lib.mkOption {
+        type = lib.types.anything;
+        description = "The default shell of the user.";
+        default = null;
+      };
+
+      sudoer = lib.mkOption {
+        type = lib.types.bool;
+        description = lib.mdDoc "Enable `sudo` commands for this user.";
+        default = false;
+      };
+    };
+  };
+in {
+  options = {
+    users.myUsers = lib.mkOption {
+      type = lib.types.attrsOf userType;
+      description = lib.mdDoc "The users for the system to create.";
+      default = {};
+    };
+  };
+
+  config = {
+    users.users = builtins.mapAttrs
+      (
+        name: user: {
+          description = lib.mkIf
+            (user.fullName != null)
+            user.fullName;
+          isNormalUser = true;
+          shell = lib.mkIf
+            (user.defaultShell != null)
+            user.defaultShell;
+          extraGroups = lib.mkIf user.sudoer [
+            "wheel"
+          ];
+        })
+      config.users.myUsers;
+  };
+}