declarative creation of ldap users and groups
This commit is contained in:
parent
757d910d13
commit
b34a1e57a7
3 changed files with 676 additions and 3 deletions
|
|
@ -24,6 +24,12 @@
|
|||
# Remove when this PR is merged:
|
||||
# https://github.com/NixOS/nixpkgs/pull/368325
|
||||
./patches/prometheusnodecertexporter.nix
|
||||
|
||||
(originPkgs.fetchpatch {
|
||||
url = "https://patch-diff.githubusercontent.com/raw/NixOS/nixpkgs/pull/374905.patch";
|
||||
hash = "sha256-9n3HYu0QM+MVLJ3FyOHAd1vdtoK+U5wNQiUwz3L6Bqs=";
|
||||
})
|
||||
|
||||
];
|
||||
patchedNixpkgs = originPkgs.applyPatches {
|
||||
name = "nixpkgs-patched";
|
||||
|
|
|
|||
|
|
@ -6,6 +6,35 @@ let
|
|||
contracts = pkgs.callPackage ../contracts {};
|
||||
|
||||
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
||||
|
||||
lldap-cli = pkgs.lldap-cli.overrideAttrs (f: p: {
|
||||
version = "0-unstable-2024-01-19";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "ibizaman";
|
||||
repo = "lldap-cli";
|
||||
rev = "e07e2cafaa68e926f1256449e4553b01a15f0a0c";
|
||||
hash = "sha256-qbXSJmx5spW9iViycRmQdYtI6KfysOxeAv7qI+sz25A=";
|
||||
};
|
||||
});
|
||||
|
||||
lldap-cli-auth = pkgs.callPackage ({ stdenvNoCC, makeWrapper }: 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 ${lldap-cli}/bin/lldap-cli $out/bin/lldap-cli \
|
||||
--set LLDAP_USERNAME "admin" \
|
||||
--run 'export LLDAP_PASSWORD="$(cat ${cfg.ldapUserPassword.result.path})"' \
|
||||
--set LLDAP_HTTPURL "http://${config.services.lldap.settings.http_host}:${toString config.services.lldap.settings.http_port}"
|
||||
'';
|
||||
}) {};
|
||||
in
|
||||
{
|
||||
options.shb.ldap = {
|
||||
|
|
@ -118,6 +147,133 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
groups = lib.mkOption {
|
||||
description = "LDAP Groups to manage declaratively.";
|
||||
default = {};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
family = {};
|
||||
}
|
||||
'';
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {};
|
||||
});
|
||||
};
|
||||
|
||||
deleteUnmanagedUsers = lib.mkOption {
|
||||
description = "Do not delete users that are not defined here.";
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
users = lib.mkOption {
|
||||
description = ''
|
||||
LDAP Users to manage declaratively.
|
||||
|
||||
Each field is provided in two versions.
|
||||
The first version, without prefix, sets the attribute
|
||||
every time the configuration is applied, overwriting any changes in the UI.
|
||||
|
||||
The second version, with the "initial" prefix, sets
|
||||
the attribute only once, on user creation. Any changes
|
||||
in the UI will survive next time the configuration is applied.
|
||||
|
||||
If both are set, the one without the "initial" prefix wins.
|
||||
'';
|
||||
default = {};
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
email = lib.mkOption {
|
||||
description = ''
|
||||
Email address.
|
||||
|
||||
Must be set: set either "email" field or "initialEmail" field.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
initialEmail = lib.mkOption {
|
||||
description = ''
|
||||
Email address.
|
||||
|
||||
Must be set: set either "email" field or "initialEmail" field.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
displayName = lib.mkOption {
|
||||
description = "Display name. Optional";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
initialDisplayName = lib.mkOption {
|
||||
description = "Display name. Optional";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
firstName = lib.mkOption {
|
||||
description = "First name. Optional";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
initialFirstName = lib.mkOption {
|
||||
description = "First name. Optional";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
lastName = lib.mkOption {
|
||||
description = "Last name. Optional.";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
initialLastName = lib.mkOption {
|
||||
description = "Last name. Optional.";
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
groups = lib.mkOption {
|
||||
description = "Groups this user is member of. The group must exist.";
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
};
|
||||
|
||||
password = lib.mkOption {
|
||||
description = "User password. Optional.";
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = contracts.secret.mkRequester {
|
||||
mode = "0440";
|
||||
owner = "lldap";
|
||||
group = "lldap";
|
||||
restartUnits = [ "lldap.service" ];
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
};
|
||||
|
||||
initialPassword = lib.mkOption {
|
||||
description = "User password. Optional.";
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = contracts.secret.mkRequester {
|
||||
mode = "0440";
|
||||
owner = "lldap";
|
||||
group = "lldap";
|
||||
restartUnits = [ "lldap.service" ];
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -171,5 +327,188 @@ in
|
|||
verbose = cfg.debug;
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
assertions = [
|
||||
(let
|
||||
uppercases = builtins.filter (n: lib.strings.toLower n != n) (lib.mapAttrsToList (uid: u: uid) cfg.users);
|
||||
in {
|
||||
assertion = uppercases == [];
|
||||
message = "Users ID for LLDAP can only be lowercase, found: ${lib.concatStringsSep "," uppercases}";
|
||||
})
|
||||
# (let
|
||||
# unknownGroups = lib.flatten(lib.mapAttrsToList (uid: u: lib.subtractLists (map (gid: g: gid) cfg.groups) u.groups) cfg.users);
|
||||
# in {
|
||||
# assertion = unknownGroups == [];
|
||||
# message = "All groups defined in user field must exist, the following ones are not defined: ${lib.concatStringsSep "," unknownGroups}";
|
||||
# })
|
||||
];
|
||||
|
||||
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.ldapUserPassword.result.path})
|
||||
export LLDAP_HTTPURL=http://${config.services.lldap.settings.http_host}:${toString config.services.lldap.settings.http_port}
|
||||
|
||||
eval $(${lldap-cli}/bin/lldap-cli login)
|
||||
''];
|
||||
|
||||
deleteGroups = [''
|
||||
allUids=(${lib.concatStringsSep " " (
|
||||
(lib.mapAttrsToList (id: g: id) cfg.groups)
|
||||
++ [ "lldap_admin" "lldap_password_manager" "lldap_strict_readonly" ])
|
||||
})
|
||||
echo All managed groups are: ''${allUids[*]}
|
||||
echo Other groups will be deleted if any
|
||||
|
||||
for uid in $(${lldap-cli}/bin/lldap-cli group list | ${pkgs.jq}/bin/jq -r 'map(.displayName)[]'); do
|
||||
if [[ ! " ''${allUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||
echo Deleting group $uid
|
||||
${lldap-cli}/bin/lldap-cli group del $uid
|
||||
fi
|
||||
done
|
||||
''];
|
||||
|
||||
createGroups = [''
|
||||
existingUids=$(${lldap-cli}/bin/lldap-cli group list | ${pkgs.jq}/bin/jq -r 'map(.displayName)[]')
|
||||
managedUids=(${lib.concatStringsSep " " (
|
||||
(lib.mapAttrsToList (id: g: id) cfg.groups)
|
||||
++ [ "lldap_admin" "lldap_password_manager" "lldap_strict_readonly" ])
|
||||
})
|
||||
echo All managed groups are: ''${managedUids[*]}
|
||||
for uid in ''${managedUids[*]}; do
|
||||
if [[ ! " ''${existingUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||
echo "Creating group $uid"
|
||||
${lldap-cli}/bin/lldap-cli group add $uid
|
||||
fi
|
||||
done
|
||||
''];
|
||||
|
||||
deleteUsers = [''
|
||||
allUids=(${lib.concatStringsSep " " (
|
||||
(lib.mapAttrsToList (uid: u: uid) cfg.users)
|
||||
++ [ "admin" ])
|
||||
})
|
||||
echo All managed users are: ''${allUids[*]}
|
||||
echo Other users will be deleted if any
|
||||
for uid in $(${lldap-cli}/bin/lldap-cli user list all | ${pkgs.jq}/bin/jq -r 'map(.id)[]'); do
|
||||
if [[ ! " ''${allUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||
echo Deleting user $uid
|
||||
${lldap-cli}/bin/lldap-cli user del $uid
|
||||
fi
|
||||
done
|
||||
''];
|
||||
|
||||
createUsers = lib.mapAttrsToList (uid: u: let
|
||||
email = if u.email != null then u.email else u.initialEmail;
|
||||
|
||||
password = if u.password != null then u.password else u.initialPassword;
|
||||
displayName = if u.displayName != null then u.displayName else u.initialDisplayName;
|
||||
firstName = if u.firstName != null then u.firstName else u.initialFirstName;
|
||||
lastName = if u.lastName != null then u.lastName else u.initialLastName;
|
||||
|
||||
allCreateAttributes =
|
||||
lib.optionals (password != null) [''-p "$(cat ${password.result.path})"'']
|
||||
++ lib.optionals (displayName != null) [''-d "${displayName}"'']
|
||||
++ lib.optionals (firstName != null) [''-f "${firstName}"'']
|
||||
++ lib.optionals (lastName != null) [''-l "${lastName}"''];
|
||||
|
||||
allUpdateAttributes =
|
||||
lib.optionals (u.email != null) [''mail "${u.email}"'']
|
||||
++ lib.optionals (u.password != null) [''password "$(cat ${u.password.result.path})"'']
|
||||
++ lib.optionals (u.displayName != null) [''display_name "${u.displayName}"'']
|
||||
++ lib.optionals (u.firstName != null) [''first_name "${u.firstName}"'']
|
||||
++ lib.optionals (u.lastName != null) [''last_name "${u.lastName}"''];
|
||||
in ''
|
||||
existingUids=($(${lldap-cli}/bin/lldap-cli user list all | ${pkgs.jq}/bin/jq -r 'map(.id)[]'))
|
||||
managedUids=(${lib.concatStringsSep " " (
|
||||
(lib.mapAttrsToList (id: u: id) cfg.users)
|
||||
++ [ "admin" ])
|
||||
})
|
||||
echo All managed users are: ''${managedUids[*]}
|
||||
echo Existing managed users are: ''${existingUids[*]}
|
||||
set -x
|
||||
for uid in ''${managedUids[*]}; do
|
||||
echo "Checking user $uid"
|
||||
if [[ ! " ''${existingUids[*]} " =~ [[:space:]]''${uid}[[:space:]] ]]; then
|
||||
echo "Creating user $uid"
|
||||
${lldap-cli}/bin/lldap-cli user add ${uid} "${email}" ${lib.concatStringsSep " " allCreateAttributes}
|
||||
else
|
||||
echo "Updating user $uid"
|
||||
${lib.concatMapStringsSep "\n " (x: "${lldap-cli}/bin/lldap-cli user update set ${uid} ${x}") allUpdateAttributes}
|
||||
fi
|
||||
done
|
||||
set +x
|
||||
'') cfg.users;
|
||||
|
||||
addToGroups = lib.mapAttrsToList (uid: u: ''
|
||||
existingUids=$(${lldap-cli}/bin/lldap-cli user group list ${uid})
|
||||
managedUids=(${lib.concatStringsSep " " u.groups})
|
||||
echo All managed groups for user ${uid} are: ''${managedUids[*]}
|
||||
for gid in ''${managedUids[*]}; do
|
||||
if [[ ! " ''${existingUids[*]} " =~ [[:space:]]''${gid}[[:space:]] ]]; then
|
||||
echo "Adding group $gid to user ${uid}"
|
||||
${lldap-cli}/bin/lldap-cli user group add \
|
||||
${uid} \
|
||||
$gid
|
||||
fi
|
||||
done
|
||||
'') cfg.users;
|
||||
|
||||
deleteFromGroups = lib.mapAttrsToList (uid: u: ''
|
||||
managedUids=(${lib.concatStringsSep " " u.groups})
|
||||
echo All managed groups for user ${uid} are: ''${managedUids[*]}
|
||||
for gid in $(${lldap-cli}/bin/lldap-cli user group list ${uid}); do
|
||||
if [[ ! " ''${managedUids[*]} " =~ [[:space:]]''${gid}[[:space:]] ]]; then
|
||||
echo "Removing group $gid from user $uid"
|
||||
${lldap-cli}/bin/lldap-cli user group del \
|
||||
${uid} \
|
||||
$gid
|
||||
fi
|
||||
done
|
||||
'') cfg.users;
|
||||
in
|
||||
lib.concatStringsSep "\n\n" (
|
||||
login
|
||||
++ deleteGroups
|
||||
++ createGroups
|
||||
++ lib.optionals cfg.deleteUnmanagedUsers deleteUsers
|
||||
++ createUsers
|
||||
++ addToGroups
|
||||
++ deleteFromGroups
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ in
|
|||
domain = "example.com";
|
||||
ldapUserPassword.result = config.shb.hardcodedsecret.ldapUserPassword.result;
|
||||
jwtSecret.result = config.shb.hardcodedsecret.jwtSecret.result;
|
||||
debug = true;
|
||||
deleteUnmanagedUsers = true;
|
||||
debug = false; # Really verbose.
|
||||
};
|
||||
shb.hardcodedsecret.ldapUserPassword = {
|
||||
request = config.shb.ldap.ldapUserPassword.request;
|
||||
|
|
@ -39,13 +40,131 @@ in
|
|||
settings.content = "jwtSecret";
|
||||
};
|
||||
|
||||
specialisation.withGroupA.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupA" = {};
|
||||
};
|
||||
};
|
||||
specialisation.withUserA.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupA" = {};
|
||||
users = {
|
||||
"user_a" = {
|
||||
email = "userA@test.com";
|
||||
displayName = "UserA";
|
||||
firstName = "User";
|
||||
lastName = "A";
|
||||
groups = [ "groupA" ];
|
||||
password.result = config.specialisation.withUserA.configuration.shb.hardcodedsecret.user_a.result;
|
||||
};
|
||||
};
|
||||
};
|
||||
shb.hardcodedsecret.user_a = {
|
||||
request = config.specialisation.withUserA.configuration.shb.ldap.users."user_a".password.request;
|
||||
settings.content = "userpasswordA"; # must be longer than 8 characters.
|
||||
};
|
||||
};
|
||||
specialisation.withOtherGroup.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupB" = {};
|
||||
groups."groupC" = {};
|
||||
users = {
|
||||
"user_a" = {
|
||||
email = "userA@test.com";
|
||||
displayName = "UserA";
|
||||
firstName = "User";
|
||||
lastName = "A";
|
||||
groups = [ "groupB" "groupC" ];
|
||||
password.result = config.specialisation.withUserA.configuration.shb.hardcodedsecret.user_a.result;
|
||||
};
|
||||
};
|
||||
};
|
||||
shb.hardcodedsecret.user_a = {
|
||||
request = config.specialisation.withUserA.configuration.shb.ldap.users."user_a".password.request;
|
||||
settings.content = "userpasswordA"; # must be longer than 8 characters.
|
||||
};
|
||||
};
|
||||
specialisation.removeFromGroup.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupB" = {};
|
||||
groups."groupC" = {};
|
||||
users = {
|
||||
"user_a" = {
|
||||
email = "userA@test.com";
|
||||
displayName = "UserA";
|
||||
firstName = "User";
|
||||
lastName = "A";
|
||||
groups = [ "groupB" ];
|
||||
password.result = config.specialisation.withUserA.configuration.shb.hardcodedsecret.user_a.result;
|
||||
};
|
||||
};
|
||||
};
|
||||
shb.hardcodedsecret.user_a = {
|
||||
request = config.specialisation.withUserA.configuration.shb.ldap.users."user_a".password.request;
|
||||
settings.content = "userpasswordA"; # must be longer than 8 characters.
|
||||
};
|
||||
};
|
||||
specialisation.changeAttributes.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupB" = {};
|
||||
users = {
|
||||
"user_a" = {
|
||||
email = "userA_2@test.com";
|
||||
displayName = "UserA_2";
|
||||
firstName = "User_2";
|
||||
lastName = "A_2";
|
||||
groups = [ "groupB" ];
|
||||
password.result = config.specialisation.withUserA.configuration.shb.hardcodedsecret.user_a.result;
|
||||
};
|
||||
};
|
||||
};
|
||||
shb.hardcodedsecret.user_a = {
|
||||
request = config.specialisation.withUserA.configuration.shb.ldap.users."user_a".password.request;
|
||||
settings.content = "userpasswordA_2"; # must be longer than 8 characters.
|
||||
};
|
||||
};
|
||||
specialisation.noChangeAttributes.configuration = {
|
||||
shb.ldap = {
|
||||
groups."groupB" = {};
|
||||
users = {
|
||||
"user_a" = {
|
||||
initialEmail = "userA_3@test.com";
|
||||
initialDisplayName = "UserA_3";
|
||||
initialFirstName = "User_3";
|
||||
initialLastName = "A_3";
|
||||
groups = [ "groupB" ];
|
||||
initialPassword.result = config.specialisation.withUserA.configuration.shb.hardcodedsecret.user_a.result;
|
||||
};
|
||||
};
|
||||
};
|
||||
shb.hardcodedsecret.user_a = {
|
||||
request = config.specialisation.withUserA.configuration.shb.ldap.users."user_a".password.request;
|
||||
settings.content = "userpasswordA_3"; # must be longer than 8 characters.
|
||||
};
|
||||
};
|
||||
specialisation.leaveUnmanagedUser.configuration = {
|
||||
shb.ldap = {
|
||||
deleteUnmanagedUsers = lib.mkForce false;
|
||||
groups."groupA" = {};
|
||||
users = {};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 ]; # nginx port
|
||||
};
|
||||
|
||||
nodes.client = {};
|
||||
|
||||
# Inspired from https://github.com/lldap/lldap/blob/33f50d13a2e2d24a3e6bb05a148246bc98090df0/example_configs/lldap-ha-auth.sh
|
||||
testScript = { nodes, ... }: ''
|
||||
testScript = { nodes, ... }: let
|
||||
withGroupA = "${nodes.server.system.build.toplevel}/specialisation/withGroupA";
|
||||
withUserA = "${nodes.server.system.build.toplevel}/specialisation/withUserA";
|
||||
withOtherGroup = "${nodes.server.system.build.toplevel}/specialisation/withOtherGroup";
|
||||
removeFromGroup = "${nodes.server.system.build.toplevel}/specialisation/removeFromGroup";
|
||||
changeAttributes = "${nodes.server.system.build.toplevel}/specialisation/changeAttributes";
|
||||
noChangeAttributes = "${nodes.server.system.build.toplevel}/specialisation/noChangeAttributes";
|
||||
leaveUnmanagedUser = "${nodes.server.system.build.toplevel}/specialisation/leaveUnmanagedUser";
|
||||
in ''
|
||||
import json
|
||||
|
||||
start_all()
|
||||
|
|
@ -82,13 +201,222 @@ in
|
|||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ """ -H "Authorization: Bearer {token}" """.format(token=token)
|
||||
+ f""" -H "Authorization: Bearer {token}" """
|
||||
+ " http://server/api/graphql "
|
||||
+ """ -d '{"variables": {"id": "admin"}, "query":"query($id:String!){user(userId:$id){displayName groups{displayName}}}"}' """
|
||||
))['data']
|
||||
|
||||
assert data['user']['displayName'] == "Administrator"
|
||||
assert data['user']['groups'][0]['displayName'] == "lldap_admin"
|
||||
|
||||
data = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ f""" -H "Authorization: Bearer {token}" """
|
||||
+ " http://server/api/graphql "
|
||||
+ """ -d '{"variables": {"id": "user_a"}, "query":"query($id:String!){user(userId:$id){displayName groups{displayName}}}"}' """
|
||||
))['data']
|
||||
|
||||
|
||||
|
||||
print(server.succeed("cat /run/current-system/sw/bin/lldap-cli"))
|
||||
|
||||
with subtest("Add groupA"):
|
||||
groups = [x["displayName"] for x in json.loads(server.succeed("lldap-cli group list"))]
|
||||
print("GROUPS=", groups)
|
||||
if "groupA" in groups:
|
||||
raise Exception("Shouldn't have found groupA yet.")
|
||||
|
||||
server.succeed(
|
||||
"${withGroupA}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
groups = [x["displayName"] for x in json.loads(server.succeed("lldap-cli group list"))]
|
||||
print("GROUPS=", groups)
|
||||
if "groupA" not in groups:
|
||||
raise Exception("Should have found groupA.")
|
||||
|
||||
with subtest("Add user_a"):
|
||||
users = [x["id"] for x in json.loads(server.succeed("lldap-cli user list all"))]
|
||||
print("USERS=", users)
|
||||
if "user_a" in users:
|
||||
raise Exception("Shouldn't have found user_a yet.")
|
||||
|
||||
server.succeed(
|
||||
"${withUserA}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
users = [x["id"] for x in json.loads(server.succeed("lldap-cli user list all"))]
|
||||
print("USERS=", users)
|
||||
if "user_a" not in users:
|
||||
raise Exception("Should have found user_a.")
|
||||
|
||||
groups = server.succeed("lldap-cli user group list user_a").splitlines()
|
||||
if "groupA" not in groups:
|
||||
raise Exception("Should have found groupA.")
|
||||
|
||||
with subtest("auth with user_a"):
|
||||
token = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ " http://server/auth/simple/login "
|
||||
+ """ -d '{"username": "user_a", "password": "userpasswordA"}' """
|
||||
))['token']
|
||||
|
||||
data = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ f""" -H "Authorization: Bearer {token}" """
|
||||
+ " http://server/api/graphql "
|
||||
+ """ -d '{"variables": {"id": "user_a"}, "query":"query($id:String!){user(userId:$id){displayName groups{displayName}}}"}' """
|
||||
))['data']
|
||||
|
||||
if data['user']['displayName'] != "UserA":
|
||||
raise Exception("DisplayName is not UserA, got:", data['user']['displayName'])
|
||||
|
||||
with subtest("With other group"):
|
||||
server.succeed(
|
||||
"${withOtherGroup}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
groups = [x["displayName"] for x in json.loads(server.succeed("lldap-cli group list"))]
|
||||
print("GROUPS=", groups)
|
||||
if "groupA" in groups:
|
||||
raise Exception("Should not have found groupA.")
|
||||
if "groupB" not in groups:
|
||||
raise Exception("Should have found groupB.")
|
||||
if "groupC" not in groups:
|
||||
raise Exception("Should have found groupC.")
|
||||
|
||||
groups = server.succeed("lldap-cli user group list user_a").splitlines()
|
||||
if "groupA" in groups:
|
||||
raise Exception("Should not have found groupA.")
|
||||
if "groupB" not in groups:
|
||||
raise Exception("Should have found groupB.")
|
||||
if "groupC" not in groups:
|
||||
raise Exception("Should have found groupC.")
|
||||
|
||||
with subtest("Remove from group"):
|
||||
server.succeed(
|
||||
"${removeFromGroup}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
groups = [x["displayName"] for x in json.loads(server.succeed("lldap-cli group list"))]
|
||||
print("GROUPS=", groups)
|
||||
if "groupA" in groups:
|
||||
raise Exception("Should not have found groupA.")
|
||||
if "groupB" not in groups:
|
||||
raise Exception("Should have found groupB.")
|
||||
if "groupC" not in groups:
|
||||
raise Exception("Should have found groupC.")
|
||||
|
||||
groups = server.succeed("lldap-cli user group list user_a").splitlines()
|
||||
if "groupA" in groups:
|
||||
raise Exception("Should not have found groupA.")
|
||||
if "groupB" not in groups:
|
||||
raise Exception("Should have found groupB.")
|
||||
if "groupC" in groups:
|
||||
raise Exception("Should not have found groupC.")
|
||||
|
||||
with subtest("change attributes"):
|
||||
server.succeed(
|
||||
"${changeAttributes}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
token = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ " http://server/auth/simple/login "
|
||||
+ """ -d '{"username": "user_a", "password": "userpasswordA_2"}' """
|
||||
))['token']
|
||||
|
||||
data = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ f""" -H "Authorization: Bearer {token}" """
|
||||
+ " http://server/api/graphql "
|
||||
+ """ -d '{"variables": {"id": "user_a"}, "query":"query($id:String!){user(userId:$id){email displayName firstName lastName}}"}' """
|
||||
))['data']
|
||||
|
||||
if data['user']['email'] != "userA_2@test.com":
|
||||
raise Exception("email is not userA_2@test.com_2, got:", data['user']['email'])
|
||||
|
||||
if data['user']['displayName'] != "UserA_2":
|
||||
raise Exception("displayName is not UserA_2, got:", data['user']['displayName'])
|
||||
|
||||
if data['user']['firstName'] != "User_2":
|
||||
raise Exception("firstName is not User_2_2, got:", data['user']['firstName'])
|
||||
|
||||
if data['user']['lastName'] != "A_2":
|
||||
raise Exception("lastName is not A_2, got:", data['user']['lastName'])
|
||||
|
||||
with subtest("do not change attributes"):
|
||||
server.succeed(
|
||||
"${noChangeAttributes}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
token = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ " http://server/auth/simple/login "
|
||||
+ """ -d '{"username": "user_a", "password": "userpasswordA_2"}' """
|
||||
))['token']
|
||||
|
||||
data = json.loads(client.succeed(
|
||||
"curl -f -s -X POST "
|
||||
+ """ -H "Content-type: application/json" """
|
||||
+ """ -H "Host: ldap.example.com" """
|
||||
+ f""" -H "Authorization: Bearer {token}" """
|
||||
+ " http://server/api/graphql "
|
||||
+ """ -d '{"variables": {"id": "user_a"}, "query":"query($id:String!){user(userId:$id){email displayName firstName lastName}}"}' """
|
||||
))['data']
|
||||
|
||||
if data['user']['email'] != "userA_2@test.com":
|
||||
raise Exception("email is not userA_2@test.com_2, got:", data['user']['email'])
|
||||
|
||||
if data['user']['displayName'] != "UserA_2":
|
||||
raise Exception("displayName is not UserA_2, got:", data['user']['displayName'])
|
||||
|
||||
if data['user']['firstName'] != "User_2":
|
||||
raise Exception("firstName is not User_2_2, got:", data['user']['firstName'])
|
||||
|
||||
if data['user']['lastName'] != "A_2":
|
||||
raise Exception("lastName is not A_2, got:", data['user']['lastName'])
|
||||
|
||||
with subtest("Delete user"):
|
||||
server.succeed(
|
||||
"${withGroupA}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
users = [x["id"] for x in json.loads(server.succeed("lldap-cli user list all"))]
|
||||
print("USERS=", users)
|
||||
if "user_a" in users:
|
||||
raise Exception("Should not have found user_a.")
|
||||
|
||||
with subtest("Add again user_a"):
|
||||
server.succeed(
|
||||
"${withUserA}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
users = [x["id"] for x in json.loads(server.succeed("lldap-cli user list all"))]
|
||||
print("USERS=", users)
|
||||
if "user_a" not in users:
|
||||
raise Exception("Should have found user_a.")
|
||||
|
||||
server.succeed(
|
||||
"${leaveUnmanagedUser}/bin/switch-to-configuration test >&2"
|
||||
)
|
||||
|
||||
users = [x["id"] for x in json.loads(server.succeed("lldap-cli user list all"))]
|
||||
print("USERS=", users)
|
||||
if "user_a" not in users:
|
||||
raise Exception("Should have found user_a.")
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue