aboutsummaryrefslogtreecommitdiff
{ config, pkgs, lib, ... }:

let

  inherit (builtins)
    genList hashString mul substring ;

  inherit (lib)
    foldl genAttrs imap mkOption stringToCharacters toLower
    types unique ;

  inherit (types)
    listOf str ;

  uid = name:
    let
      dec = {
        "0" =  0; "1" =  1; "2" =  2; "3" =  3;
        "4" =  4; "5" =  5; "6" =  6; "7" =  7;
        "8" =  8; "9" =  9; "a" = 10; "b" = 11;
        "c" = 12; "d" = 13; "e" = 14; "f" = 15;
      };
      base = 1000000000; # 2^32 > base + 16^7
      hex = toLower (substring 0 7 (hashString "sha1" name));
      pow = b: n: foldl mul 1 (genList (_: b) n);
      digits = imap (i: d: {m = pow 16 (i - 1); d = d;}) (stringToCharacters hex);
      f = a: {m, d}: a + m * dec.${d};

    in foldl f base digits;

  daemons = config.nixsap.system.users.daemons;
  normal = config.nixsap.system.users.normal;
  groups = config.nixsap.system.groups;

  mkGroup = name: { gid = uid name; };
  mkDaemonUser = name:
    {
      isNormalUser = false;
      uid = uid name;
      group = name;
    };

  mkNormalUser = name:
    {
      isNormalUser = true;
      uid = uid name;
    };

in {
  options.nixsap.system = {
    users.daemons = mkOption {
      type = listOf str;
      description = "List of system users with automatic UID and group";
      default = [];
    };
    users.normal = mkOption {
      type = listOf str;
      description = "List of regular users with automatic UID";
      default = [];
    };
    users.sysops = mkOption {
      description = ''
        List of local users with special roles in applications or system-wide.
        The users in this list are not create automatically.
      '';
      type = listOf str;
      default = [];
    };
    groups = mkOption {
      type = listOf str;
      description = "List of groups with automatic GID";
      default = [];
    };
  };

  # XXX: Modules for automatic unicity of user names:
  imports = [
    { users.groups = genAttrs (unique (daemons ++ groups)) mkGroup; }
    { users.users = genAttrs daemons mkDaemonUser; }
    { users.users = genAttrs normal mkNormalUser; }
  ];
}