Loading nixos/modules/services/misc/portunus.nix +49 −52 Original line number Diff line number Diff line { config, lib, pkgs, ... }: with lib; let cfg = config.services.portunus; in { options.services.portunus = { enable = mkEnableOption "Portunus, a self-contained user/group management and authentication service for LDAP"; enable = lib.mkEnableOption "Portunus, a self-contained user/group management and authentication service for LDAP"; domain = mkOption { type = types.str; domain = lib.mkOption { type = lib.types.str; example = "sso.example.com"; description = "Subdomain which gets reverse proxied to Portunus webserver."; }; port = mkOption { type = types.port; port = lib.mkOption { type = lib.types.port; default = 8080; description = '' Port where the Portunus webserver should listen on. Loading @@ -26,10 +23,10 @@ in ''; }; package = mkPackageOption pkgs "portunus" { }; package = lib.mkPackageOption pkgs "portunus" { }; seedPath = mkOption { type = types.nullOr types.path; seedPath = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; description = '' Path to a portunus seed file in json format. Loading @@ -46,26 +43,26 @@ in ''; }; stateDir = mkOption { type = types.path; stateDir = lib.mkOption { type = lib.types.path; default = "/var/lib/portunus"; description = "Path where Portunus stores its state."; }; user = mkOption { type = types.str; user = lib.mkOption { type = lib.types.str; default = "portunus"; description = "User account under which Portunus runs its webserver."; }; group = mkOption { type = types.str; group = lib.mkOption { type = lib.types.str; default = "portunus"; description = "Group account under which Portunus runs its webserver."; }; dex = { enable = mkEnableOption '' enable = lib.mkEnableOption '' Dex ldap connector. To activate dex, first a search user must be created in the Portunus web ui Loading @@ -73,15 +70,15 @@ in in the [](#opt-services.dex.environmentFile) setting ''; oidcClients = mkOption { type = types.listOf (types.submodule { oidcClients = lib.mkOption { type = lib.types.listOf (lib.types.submodule { options = { callbackURL = mkOption { type = types.str; callbackURL = lib.mkOption { type = lib.types.str; description = "URL where the OIDC client should redirect"; }; id = mkOption { type = types.str; id = lib.mkOption { type = lib.types.str; description = "ID of the OIDC client"; }; }; Loading @@ -105,23 +102,23 @@ in ''; }; port = mkOption { type = types.port; port = lib.mkOption { type = lib.types.port; default = 5556; description = "Port where dex should listen on."; }; }; ldap = { package = mkOption { type = types.package; package = lib.mkOption { type = lib.types.package; default = pkgs.openldap; defaultText = lib.literalExpression "pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }"; description = "The OpenLDAP package to use."; }; searchUserName = mkOption { type = types.str; searchUserName = lib.mkOption { type = lib.types.str; default = ""; example = "admin"; description = '' Loading @@ -130,8 +127,8 @@ in ''; }; suffix = mkOption { type = types.str; suffix = lib.mkOption { type = lib.types.str; example = "dc=example,dc=org"; description = '' The DN of the topmost entry in your LDAP directory. Loading @@ -139,8 +136,8 @@ in ''; }; tls = mkOption { type = types.bool; tls = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to enable LDAPS protocol. Loading @@ -151,21 +148,21 @@ in ''; }; user = mkOption { type = types.str; user = lib.mkOption { type = lib.types.str; default = "openldap"; description = "User account under which Portunus runs its LDAP server."; }; group = mkOption { type = types.str; group = lib.mkOption { type = lib.types.str; default = "openldap"; description = "Group account under which Portunus runs its LDAP server."; }; }; }; config = mkIf cfg.enable { config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.dex.enable -> cfg.ldap.searchUserName != ""; Loading @@ -177,13 +174,13 @@ in environment.systemPackages = [ cfg.ldap.package ]; # allow connecting via ldaps /w certificate without opening ports networking.hosts = mkIf cfg.ldap.tls { networking.hosts = lib.mkIf cfg.ldap.tls { "::1" = [ cfg.domain ]; "127.0.0.1" = [ cfg.domain ]; }; services = { dex = mkIf cfg.dex.enable { dex = lib.mkIf cfg.dex.enable { enable = true; settings = { issuer = "https://${cfg.domain}/dex"; Loading Loading @@ -219,7 +216,7 @@ in }; }]; staticClients = forEach cfg.dex.oidcClients (client: { staticClients = lib.forEach cfg.dex.oidcClients (client: { inherit (client) id; redirectURIs = [ client.callbackURL ]; name = "OIDC for ${client.id}"; Loading @@ -232,7 +229,7 @@ in }; systemd.services = { dex = mkIf cfg.dex.enable { dex = lib.mkIf cfg.dex.enable { serviceConfig = { # `dex.service` is super locked down out of the box, but we need some # place to write the SQLite database. This creates $STATE_DIRECTORY below Loading Loading @@ -261,9 +258,9 @@ in PORTUNUS_SLAPD_GROUP = cfg.ldap.group; PORTUNUS_SLAPD_USER = cfg.ldap.user; PORTUNUS_SLAPD_SCHEMA_DIR = "${cfg.ldap.package}/etc/schema"; } // (optionalAttrs (cfg.seedPath != null) ({ } // (lib.optionalAttrs (cfg.seedPath != null) ({ PORTUNUS_SEED_PATH = cfg.seedPath; })) // (optionalAttrs cfg.ldap.tls ( })) // (lib.optionalAttrs cfg.ldap.tls ( let acmeDirectory = config.security.acme.certs."${cfg.domain}".directory; in Loading @@ -277,14 +274,14 @@ in }; }; users.users = mkMerge [ (mkIf (cfg.ldap.user == "openldap") { users.users = lib.mkMerge [ (lib.mkIf (cfg.ldap.user == "openldap") { openldap = { group = cfg.ldap.group; isSystemUser = true; }; }) (mkIf (cfg.user == "portunus") { (lib.mkIf (cfg.user == "portunus") { portunus = { group = cfg.group; isSystemUser = true; Loading @@ -292,15 +289,15 @@ in }) ]; users.groups = mkMerge [ (mkIf (cfg.ldap.user == "openldap") { users.groups = lib.mkMerge [ (lib.mkIf (cfg.ldap.user == "openldap") { openldap = { }; }) (mkIf (cfg.user == "portunus") { (lib.mkIf (cfg.user == "portunus") { portunus = { }; }) ]; }; meta.maintainers = [ maintainers.majewsky ] ++ teams.c3d2.members; meta.maintainers = [ lib.maintainers.majewsky ] ++ lib.teams.c3d2.members; } Loading
nixos/modules/services/misc/portunus.nix +49 −52 Original line number Diff line number Diff line { config, lib, pkgs, ... }: with lib; let cfg = config.services.portunus; in { options.services.portunus = { enable = mkEnableOption "Portunus, a self-contained user/group management and authentication service for LDAP"; enable = lib.mkEnableOption "Portunus, a self-contained user/group management and authentication service for LDAP"; domain = mkOption { type = types.str; domain = lib.mkOption { type = lib.types.str; example = "sso.example.com"; description = "Subdomain which gets reverse proxied to Portunus webserver."; }; port = mkOption { type = types.port; port = lib.mkOption { type = lib.types.port; default = 8080; description = '' Port where the Portunus webserver should listen on. Loading @@ -26,10 +23,10 @@ in ''; }; package = mkPackageOption pkgs "portunus" { }; package = lib.mkPackageOption pkgs "portunus" { }; seedPath = mkOption { type = types.nullOr types.path; seedPath = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; description = '' Path to a portunus seed file in json format. Loading @@ -46,26 +43,26 @@ in ''; }; stateDir = mkOption { type = types.path; stateDir = lib.mkOption { type = lib.types.path; default = "/var/lib/portunus"; description = "Path where Portunus stores its state."; }; user = mkOption { type = types.str; user = lib.mkOption { type = lib.types.str; default = "portunus"; description = "User account under which Portunus runs its webserver."; }; group = mkOption { type = types.str; group = lib.mkOption { type = lib.types.str; default = "portunus"; description = "Group account under which Portunus runs its webserver."; }; dex = { enable = mkEnableOption '' enable = lib.mkEnableOption '' Dex ldap connector. To activate dex, first a search user must be created in the Portunus web ui Loading @@ -73,15 +70,15 @@ in in the [](#opt-services.dex.environmentFile) setting ''; oidcClients = mkOption { type = types.listOf (types.submodule { oidcClients = lib.mkOption { type = lib.types.listOf (lib.types.submodule { options = { callbackURL = mkOption { type = types.str; callbackURL = lib.mkOption { type = lib.types.str; description = "URL where the OIDC client should redirect"; }; id = mkOption { type = types.str; id = lib.mkOption { type = lib.types.str; description = "ID of the OIDC client"; }; }; Loading @@ -105,23 +102,23 @@ in ''; }; port = mkOption { type = types.port; port = lib.mkOption { type = lib.types.port; default = 5556; description = "Port where dex should listen on."; }; }; ldap = { package = mkOption { type = types.package; package = lib.mkOption { type = lib.types.package; default = pkgs.openldap; defaultText = lib.literalExpression "pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }"; description = "The OpenLDAP package to use."; }; searchUserName = mkOption { type = types.str; searchUserName = lib.mkOption { type = lib.types.str; default = ""; example = "admin"; description = '' Loading @@ -130,8 +127,8 @@ in ''; }; suffix = mkOption { type = types.str; suffix = lib.mkOption { type = lib.types.str; example = "dc=example,dc=org"; description = '' The DN of the topmost entry in your LDAP directory. Loading @@ -139,8 +136,8 @@ in ''; }; tls = mkOption { type = types.bool; tls = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to enable LDAPS protocol. Loading @@ -151,21 +148,21 @@ in ''; }; user = mkOption { type = types.str; user = lib.mkOption { type = lib.types.str; default = "openldap"; description = "User account under which Portunus runs its LDAP server."; }; group = mkOption { type = types.str; group = lib.mkOption { type = lib.types.str; default = "openldap"; description = "Group account under which Portunus runs its LDAP server."; }; }; }; config = mkIf cfg.enable { config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.dex.enable -> cfg.ldap.searchUserName != ""; Loading @@ -177,13 +174,13 @@ in environment.systemPackages = [ cfg.ldap.package ]; # allow connecting via ldaps /w certificate without opening ports networking.hosts = mkIf cfg.ldap.tls { networking.hosts = lib.mkIf cfg.ldap.tls { "::1" = [ cfg.domain ]; "127.0.0.1" = [ cfg.domain ]; }; services = { dex = mkIf cfg.dex.enable { dex = lib.mkIf cfg.dex.enable { enable = true; settings = { issuer = "https://${cfg.domain}/dex"; Loading Loading @@ -219,7 +216,7 @@ in }; }]; staticClients = forEach cfg.dex.oidcClients (client: { staticClients = lib.forEach cfg.dex.oidcClients (client: { inherit (client) id; redirectURIs = [ client.callbackURL ]; name = "OIDC for ${client.id}"; Loading @@ -232,7 +229,7 @@ in }; systemd.services = { dex = mkIf cfg.dex.enable { dex = lib.mkIf cfg.dex.enable { serviceConfig = { # `dex.service` is super locked down out of the box, but we need some # place to write the SQLite database. This creates $STATE_DIRECTORY below Loading Loading @@ -261,9 +258,9 @@ in PORTUNUS_SLAPD_GROUP = cfg.ldap.group; PORTUNUS_SLAPD_USER = cfg.ldap.user; PORTUNUS_SLAPD_SCHEMA_DIR = "${cfg.ldap.package}/etc/schema"; } // (optionalAttrs (cfg.seedPath != null) ({ } // (lib.optionalAttrs (cfg.seedPath != null) ({ PORTUNUS_SEED_PATH = cfg.seedPath; })) // (optionalAttrs cfg.ldap.tls ( })) // (lib.optionalAttrs cfg.ldap.tls ( let acmeDirectory = config.security.acme.certs."${cfg.domain}".directory; in Loading @@ -277,14 +274,14 @@ in }; }; users.users = mkMerge [ (mkIf (cfg.ldap.user == "openldap") { users.users = lib.mkMerge [ (lib.mkIf (cfg.ldap.user == "openldap") { openldap = { group = cfg.ldap.group; isSystemUser = true; }; }) (mkIf (cfg.user == "portunus") { (lib.mkIf (cfg.user == "portunus") { portunus = { group = cfg.group; isSystemUser = true; Loading @@ -292,15 +289,15 @@ in }) ]; users.groups = mkMerge [ (mkIf (cfg.ldap.user == "openldap") { users.groups = lib.mkMerge [ (lib.mkIf (cfg.ldap.user == "openldap") { openldap = { }; }) (mkIf (cfg.user == "portunus") { (lib.mkIf (cfg.user == "portunus") { portunus = { }; }) ]; }; meta.maintainers = [ maintainers.majewsky ] ++ teams.c3d2.members; meta.maintainers = [ lib.maintainers.majewsky ] ++ lib.teams.c3d2.members; }