wip lldap declarative
This commit is contained in:
parent
7dfabe6f17
commit
76a07d5edf
3 changed files with 215 additions and 1 deletions
|
@ -24,6 +24,10 @@
|
||||||
url = "https://github.com/NixOS/nixpkgs/pull/317107.patch";
|
url = "https://github.com/NixOS/nixpkgs/pull/317107.patch";
|
||||||
hash = "sha256-6SfqnPLPxJHckXNU03HA0X03u9Ynn3baQ2HHMq5FkIc=";
|
hash = "sha256-6SfqnPLPxJHckXNU03HA0X03u9Ynn3baQ2HHMq5FkIc=";
|
||||||
})
|
})
|
||||||
|
(originPkgs.fetchpatch {
|
||||||
|
url = "https://patch-diff.githubusercontent.com/raw/NixOS/nixpkgs/pull/304721.patch";
|
||||||
|
sha256 = "sha256-AOTtqbsDkykJKeE/e0Y2IscSHZ56vLEbl7lzxd+QfKo=";
|
||||||
|
})
|
||||||
];
|
];
|
||||||
patchedNixpkgs = originPkgs.applyPatches {
|
patchedNixpkgs = originPkgs.applyPatches {
|
||||||
name = "nixpkgs-patched";
|
name = "nixpkgs-patched";
|
||||||
|
|
|
@ -6,6 +6,24 @@ let
|
||||||
contracts = pkgs.callPackage ../contracts {};
|
contracts = pkgs.callPackage ../contracts {};
|
||||||
|
|
||||||
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
||||||
|
|
||||||
|
lldap-cli-auth = pkgs.callPackage ({ stdenvNoCC, makeWrapper, lldap-cli }: stdenvNoCC.mkDerivation {
|
||||||
|
name = "lldap-cli";
|
||||||
|
|
||||||
|
src = lldap-cli;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
makeWrapper
|
||||||
|
];
|
||||||
|
|
||||||
|
# No quotes around the value for LLDAP_PASSWORD because we want the value to not be enclosed in quotes.
|
||||||
|
installPhase = ''
|
||||||
|
makeWrapper ${pkgs.lldap-cli}/bin/lldap-cli $out/bin/lldap-cli \
|
||||||
|
--set LLDAP_USERNAME "admin" \
|
||||||
|
--set LLDAP_PASSWORD $(cat ${cfg.ldapUserPasswordFile}) \
|
||||||
|
--set LLDAP_HTTPURL "http://${config.services.lldap.settings.http_host}:${toString config.services.lldap.settings.http_port}"
|
||||||
|
'';
|
||||||
|
}) {};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.shb.ldap = {
|
options.shb.ldap = {
|
||||||
|
@ -69,8 +87,59 @@ in
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
groups = lib.mkOption {
|
||||||
|
description = "LDAP Groups to manage declaratively.";
|
||||||
|
default = {};
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
family = {};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule {
|
||||||
|
options = {};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users = lib.mkOption {
|
||||||
|
description = "LDAP Users to manage declaratively.";
|
||||||
|
default = {};
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
email = lib.mkOption {
|
||||||
|
description = "Email address.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
displayName = lib.mkOption {
|
||||||
|
description = "Display name.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
firstName = lib.mkOption {
|
||||||
|
description = "First name.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
lastName = lib.mkOption {
|
||||||
|
description = "Last name.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
groups = lib.mkOption {
|
||||||
|
description = "Groups this user is member of. The group must exist.";
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "File containing the user's password.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
@ -126,6 +195,105 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
lldap-cli-auth
|
||||||
|
];
|
||||||
|
|
||||||
|
# $ lldap-cli schema attribute user list
|
||||||
|
#
|
||||||
|
# Name Type Is list Is visible Is editable
|
||||||
|
# ---- ---- ------- ---------- -----------
|
||||||
|
# avatar JpegPhoto false true true
|
||||||
|
# creation_date DateTime false true false
|
||||||
|
# display_name String false true true
|
||||||
|
# first_name String false true true
|
||||||
|
# last_name String false true true
|
||||||
|
# mail String false true true
|
||||||
|
# user_id String false true false
|
||||||
|
# uuid String false true false
|
||||||
|
|
||||||
|
|
||||||
|
# $ lldap-cli schema attribute group list
|
||||||
|
#
|
||||||
|
# Name Type Is list Is visible Is editable
|
||||||
|
# ---- ---- ------- ---------- -----------
|
||||||
|
# creation_date DateTime false true false
|
||||||
|
# display_name String false true true
|
||||||
|
# group_id Integer false true false
|
||||||
|
# uuid String false true false
|
||||||
|
|
||||||
|
systemd.services.lldap.postStart =
|
||||||
|
let
|
||||||
|
configFile = (pkgs.formats.toml {}).generate "lldap_config.toml" config.services.lldap.settings;
|
||||||
|
|
||||||
|
login = [''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
export LLDAP_USERNAME=admin
|
||||||
|
export LLDAP_PASSWORD=$(cat ${cfg.ldapUserPasswordFile})
|
||||||
|
export LLDAP_HTTPURL=http://${config.services.lldap.settings.http_host}:${toString config.services.lldap.settings.http_port}
|
||||||
|
|
||||||
|
eval $(${pkgs.lldap-cli}/bin/lldap-cli login)
|
||||||
|
|
||||||
|
set -x
|
||||||
|
''];
|
||||||
|
|
||||||
|
deleteGroups = [''
|
||||||
|
allUids=(${lib.concatStringsSep " " (
|
||||||
|
(lib.mapAttrsToList (uid: g: uid) cfg.groups)
|
||||||
|
++ [ "lldap_admin" "lldap_password_manager" "lldap_strict_readonly" ])
|
||||||
|
})
|
||||||
|
echo All managed groups are: $allUids
|
||||||
|
echo Other groups will be deleted
|
||||||
|
for uid in $(${pkgs.lldap-cli}/bin/lldap-cli group list); do
|
||||||
|
if [[ ! " ''${allUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli group del $uid
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
''];
|
||||||
|
|
||||||
|
createGroups = lib.mapAttrsToList (uid: g: ''
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli group add ${uid}
|
||||||
|
'') cfg.groups;
|
||||||
|
|
||||||
|
deleteUsers = [''
|
||||||
|
allUids=(${lib.concatStringsSep " " (
|
||||||
|
(lib.mapAttrsToList (uid: u: uid) cfg.users)
|
||||||
|
++ [ "admin" ])
|
||||||
|
})
|
||||||
|
for uid in $(${pkgs.lldap-cli}/bin/lldap-cli user list uid); do
|
||||||
|
if [[ ! " ''${allUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user del $uid
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
''];
|
||||||
|
|
||||||
|
createUsers = lib.mapAttrsToList (uid: u: ''
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user add ${uid} "${u.email}"
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user update set ${uid} password "$(cat ${u.passwordFile})"
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user update set ${uid} mail "${u.email}"
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user update set ${uid} display_name "${u.displayName}"
|
||||||
|
# ${pkgs.lldap-cli}/bin/lldap-cli user update set ${uid} first_name "${u.firstName}"
|
||||||
|
# ${pkgs.lldap-cli}/bin/lldap-cli user update set ${uid} last_name "${u.lastName}"
|
||||||
|
'') cfg.users;
|
||||||
|
|
||||||
|
addToGroups = lib.mapAttrsToList (uid: u: lib.concatMapStringsSep "\n" (g: ''
|
||||||
|
${pkgs.lldap-cli}/bin/lldap-cli user group add \
|
||||||
|
${uid} \
|
||||||
|
${g}
|
||||||
|
'') u.groups) cfg.users;
|
||||||
|
in
|
||||||
|
lib.concatStringsSep "\n\n" (
|
||||||
|
login
|
||||||
|
++ deleteGroups
|
||||||
|
++ createGroups
|
||||||
|
++ deleteUsers
|
||||||
|
++ createUsers
|
||||||
|
++ addToGroups
|
||||||
|
);
|
||||||
|
|
||||||
shb.backup.instances.lldap = {
|
shb.backup.instances.lldap = {
|
||||||
sourceDirectories = [
|
sourceDirectories = [
|
||||||
"/var/lib/lldap"
|
"/var/lib/lldap"
|
||||||
|
|
|
@ -27,6 +27,20 @@ in
|
||||||
ldapUserPasswordFile = pkgs.writeText "user_password" "securepw";
|
ldapUserPasswordFile = pkgs.writeText "user_password" "securepw";
|
||||||
jwtSecretFile = pkgs.writeText "jwt_secret" "securejwtsecret";
|
jwtSecretFile = pkgs.writeText "jwt_secret" "securejwtsecret";
|
||||||
debug = true;
|
debug = true;
|
||||||
|
|
||||||
|
# groups = {
|
||||||
|
# "test-group" = {};
|
||||||
|
# };
|
||||||
|
# users = {
|
||||||
|
# "42" = {
|
||||||
|
# email = "my@test.com";
|
||||||
|
# displayName = "My Test";
|
||||||
|
# firstName = "My";
|
||||||
|
# lastName = "My";
|
||||||
|
# groups = [ "test-group" ];
|
||||||
|
# passwordFile = pkgs.writeText "userpw" "userpw78";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
};
|
};
|
||||||
networking.firewall.allowedTCPPorts = [ 80 ]; # nginx port
|
networking.firewall.allowedTCPPorts = [ 80 ]; # nginx port
|
||||||
};
|
};
|
||||||
|
@ -78,6 +92,34 @@ in
|
||||||
|
|
||||||
assert data['user']['displayName'] == "Administrator"
|
assert data['user']['displayName'] == "Administrator"
|
||||||
assert data['user']['groups'][0]['displayName'] == "lldap_admin"
|
assert data['user']['groups'][0]['displayName'] == "lldap_admin"
|
||||||
|
|
||||||
|
# with subtest("check user exists"):
|
||||||
|
# ids = server.succeed("lldap-cli user list uid").splitlines()
|
||||||
|
# print(ids)
|
||||||
|
# if "42" not in ids:
|
||||||
|
# raise Exception("Did not find user for email my@test.com")
|
||||||
|
|
||||||
|
# groups = server.succeed("lldap-cli user group list 42").splitlines()
|
||||||
|
# print(groups)
|
||||||
|
# if "test-group" not in groups:
|
||||||
|
# raise Exception("Did not find group for email my@test.com")
|
||||||
|
|
||||||
|
# with subtest("service updates attributes"):
|
||||||
|
# server.succeed("lldap-cli user update set 42 mail other@test.com")
|
||||||
|
|
||||||
|
# emails = server.succeed("lldap-cli user list email").splitlines()
|
||||||
|
# print("after update", emails)
|
||||||
|
# if "my@test.com" in emails:
|
||||||
|
# raise Exception("Did not find user for email other@test.com")
|
||||||
|
|
||||||
|
# server.succeed("systemctl restart lldap")
|
||||||
|
|
||||||
|
# emails = server.succeed("lldap-cli user list email").splitlines()
|
||||||
|
# print("after restart", emails)
|
||||||
|
# if "my@test.com" not in emails:
|
||||||
|
# raise Exception("Did not find user for email my@test.com")
|
||||||
|
|
||||||
|
# print(server.succeed("systemctl cat lldap | grep Post"))
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue