style: format tree
This commit is contained in:
177
auth/kanidm.nix
177
auth/kanidm.nix
@@ -1,8 +1,9 @@
|
||||
{ config
|
||||
, lib
|
||||
, options
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
@@ -40,7 +41,9 @@ let
|
||||
cfg = config.services.kanidm;
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
# Remove null values, so we can document optional values that don't end up in the generated TOML file.
|
||||
filterConfig = converge (a: filterAttrsRecursive (_: v: v != null) (builtins.removeAttrs a [ "provision" ]));
|
||||
filterConfig = converge (
|
||||
a: filterAttrsRecursive (_: v: v != null) (builtins.removeAttrs a [ "provision" ])
|
||||
);
|
||||
serverConfigFile = settingsFormat.generate "server.toml" (filterConfig cfg.serverSettings);
|
||||
clientConfigFile = settingsFormat.generate "kanidm-config.toml" (filterConfig cfg.clientSettings);
|
||||
unixConfigFile = settingsFormat.generate "kanidm-unixd.toml" (filterConfig cfg.unixSettings);
|
||||
@@ -54,17 +57,16 @@ let
|
||||
# paths, no new bind mount is added. Adding subpaths caused problems on ofborg.
|
||||
hasPrefixInList =
|
||||
list: newPath: any (path: hasPrefix (builtins.toString path) (builtins.toString newPath)) list;
|
||||
mergePaths = foldl'
|
||||
(
|
||||
merged: newPath:
|
||||
let
|
||||
# If the new path is a prefix to some existing path, we need to filter it out
|
||||
filteredPaths = filter (p: !hasPrefix (builtins.toString newPath) (builtins.toString p)) merged;
|
||||
# If a prefix of the new path is already in the list, do not add it
|
||||
filteredNew = optional (!hasPrefixInList filteredPaths newPath) newPath;
|
||||
in
|
||||
filteredPaths ++ filteredNew
|
||||
) [ ];
|
||||
mergePaths = foldl' (
|
||||
merged: newPath:
|
||||
let
|
||||
# If the new path is a prefix to some existing path, we need to filter it out
|
||||
filteredPaths = filter (p: !hasPrefix (builtins.toString newPath) (builtins.toString p)) merged;
|
||||
# If a prefix of the new path is already in the list, do not add it
|
||||
filteredNew = optional (!hasPrefixInList filteredPaths newPath) newPath;
|
||||
in
|
||||
filteredPaths ++ filteredNew
|
||||
) [ ];
|
||||
|
||||
defaultServiceConfig = {
|
||||
# Setting the type to notify enables additional healthchecks, ensuring units
|
||||
@@ -127,19 +129,20 @@ let
|
||||
filterPresent = filterAttrs (_: v: v.present);
|
||||
|
||||
selfprivacy-admin-groups-regex = "^sp\.([[:alnum:]]+\.|)admins$";
|
||||
is-selfprivacy-admin-group = name:
|
||||
! builtins.isNull (builtins.match selfprivacy-admin-groups-regex name);
|
||||
is-selfprivacy-admin-group =
|
||||
name: !builtins.isNull (builtins.match selfprivacy-admin-groups-regex name);
|
||||
|
||||
isGroupNonOverwritable = g: false
|
||||
|| ! g ? members
|
||||
isGroupNonOverwritable =
|
||||
g:
|
||||
false
|
||||
|| !g ? members
|
||||
|| g ? members && g.members == [ ]
|
||||
|| g ? members && builtins.any is-selfprivacy-admin-group g.members;
|
||||
|
||||
provisionStateJson = pkgs.writeText "provision-state.json" (
|
||||
builtins.toJSON {
|
||||
inherit (cfg.provision) persons systems;
|
||||
groups =
|
||||
lib.attrsets.filterAttrs (_n: v: ! isGroupNonOverwritable v) cfg.provision.groups;
|
||||
groups = lib.attrsets.filterAttrs (_n: v: !isGroupNonOverwritable v) cfg.provision.groups;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -182,8 +185,9 @@ let
|
||||
fi
|
||||
'';
|
||||
|
||||
groupsToCreateAndPopulate =
|
||||
lib.attrsets.filterAttrs (_n: isGroupNonOverwritable) cfg.provision.groups;
|
||||
groupsToCreateAndPopulate = lib.attrsets.filterAttrs (
|
||||
_n: isGroupNonOverwritable
|
||||
) cfg.provision.groups;
|
||||
|
||||
createGroups = ''
|
||||
for group_name in ${lib.strings.concatStringsSep " " (builtins.attrNames groupsToCreateAndPopulate)}
|
||||
@@ -199,9 +203,9 @@ let
|
||||
done
|
||||
'';
|
||||
|
||||
createAndPopulateGroups =
|
||||
lib.concatLines ([ createGroups ]
|
||||
++ (lib.mapAttrsToList populateGroup groupsToCreateAndPopulate));
|
||||
createAndPopulateGroups = lib.concatLines (
|
||||
[ createGroups ] ++ (lib.mapAttrsToList populateGroup groupsToCreateAndPopulate)
|
||||
);
|
||||
|
||||
postStartScript = pkgs.writeShellScript "post-start" ''
|
||||
set -euo pipefail
|
||||
@@ -250,11 +254,11 @@ let
|
||||
last (splitString "]:" cfg.serverSettings.bindaddress)
|
||||
else
|
||||
# ipv4:
|
||||
if hasInfix "." cfg.serverSettings.bindaddress then
|
||||
last (splitString ":" cfg.serverSettings.bindaddress)
|
||||
# default is 8443
|
||||
else
|
||||
"8443";
|
||||
if hasInfix "." cfg.serverSettings.bindaddress then
|
||||
last (splitString ":" cfg.serverSettings.bindaddress)
|
||||
# default is 8443
|
||||
else
|
||||
"8443";
|
||||
in
|
||||
{
|
||||
options.services.kanidm = {
|
||||
@@ -476,11 +480,9 @@ in
|
||||
config.members = concatLists (
|
||||
flip mapAttrsToList cfg.provision.persons (
|
||||
person: personCfg:
|
||||
optional
|
||||
(
|
||||
personCfg.present && builtins.elem groupSubmod.config._module.args.name personCfg.groups
|
||||
)
|
||||
person
|
||||
optional (
|
||||
personCfg.present && builtins.elem groupSubmod.config._module.args.name personCfg.groups
|
||||
) person
|
||||
)
|
||||
);
|
||||
})
|
||||
@@ -683,12 +685,9 @@ in
|
||||
++ entityList "oauth2" cfg.provision.systems.oauth2;
|
||||
|
||||
# Accumulate entities by name. Track corresponding entity types for later duplicate check.
|
||||
entitiesByName = foldl'
|
||||
(
|
||||
acc: { type, name }: acc // { ${name} = (acc.${name} or [ ]) ++ [ type ]; }
|
||||
)
|
||||
{ }
|
||||
entities;
|
||||
entitiesByName = foldl' (
|
||||
acc: { type, name }: acc // { ${name} = (acc.${name} or [ ]) ++ [ type ]; }
|
||||
) { } entities;
|
||||
|
||||
assertGroupsKnown =
|
||||
opt: groups:
|
||||
@@ -800,59 +799,59 @@ in
|
||||
]
|
||||
++ flip mapAttrsToList (filterPresent cfg.provision.persons) (
|
||||
person: personCfg:
|
||||
assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
|
||||
assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
|
||||
)
|
||||
++ flip mapAttrsToList (filterPresent cfg.provision.groups) (
|
||||
group: groupCfg:
|
||||
assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
|
||||
assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
|
||||
)
|
||||
++ concatLists (
|
||||
flip mapAttrsToList (filterPresent cfg.provision.systems.oauth2) (
|
||||
oauth2: oauth2Cfg:
|
||||
[
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.scopeMaps" (
|
||||
attrNames oauth2Cfg.scopeMaps
|
||||
))
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.supplementaryScopeMaps" (
|
||||
attrNames oauth2Cfg.supplementaryScopeMaps
|
||||
))
|
||||
]
|
||||
++ concatLists (
|
||||
flip mapAttrsToList oauth2Cfg.claimMaps (
|
||||
claim: claimCfg: [
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim}.valuesByGroup" (
|
||||
attrNames claimCfg.valuesByGroup
|
||||
))
|
||||
# At least one group must map to a value in each claim map
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer)
|
||||
-> any (xs: xs != [ ]) (attrValues claimCfg.valuesByGroup);
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim} does not specify any values for any group";
|
||||
}
|
||||
# Public clients cannot define a basic secret
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) -> oauth2Cfg.basicSecretFile == null;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot specify a basic secret";
|
||||
}
|
||||
# Public clients cannot disable PKCE
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && oauth2Cfg.public)
|
||||
-> !oauth2Cfg.allowInsecureClientDisablePkce;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot disable PKCE";
|
||||
}
|
||||
# Non-public clients cannot enable localhost redirects
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && !oauth2Cfg.public)
|
||||
-> !oauth2Cfg.enableLocalhostRedirects;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a non-public client and thus cannot enable localhost redirects";
|
||||
}
|
||||
]
|
||||
)
|
||||
[
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.scopeMaps" (
|
||||
attrNames oauth2Cfg.scopeMaps
|
||||
))
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.supplementaryScopeMaps" (
|
||||
attrNames oauth2Cfg.supplementaryScopeMaps
|
||||
))
|
||||
]
|
||||
++ concatLists (
|
||||
flip mapAttrsToList oauth2Cfg.claimMaps (
|
||||
claim: claimCfg: [
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim}.valuesByGroup" (
|
||||
attrNames claimCfg.valuesByGroup
|
||||
))
|
||||
# At least one group must map to a value in each claim map
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer)
|
||||
-> any (xs: xs != [ ]) (attrValues claimCfg.valuesByGroup);
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim} does not specify any values for any group";
|
||||
}
|
||||
# Public clients cannot define a basic secret
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) -> oauth2Cfg.basicSecretFile == null;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot specify a basic secret";
|
||||
}
|
||||
# Public clients cannot disable PKCE
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && oauth2Cfg.public)
|
||||
-> !oauth2Cfg.allowInsecureClientDisablePkce;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot disable PKCE";
|
||||
}
|
||||
# Non-public clients cannot enable localhost redirects
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable && cfg.enableServer && !oauth2Cfg.public)
|
||||
-> !oauth2Cfg.enableLocalhostRedirects;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a non-public client and thus cannot enable localhost redirects";
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user