mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-04-10 01:17:19 +00:00
Add QA tests for TOTP
This commit is contained in:
parent
24ae913d68
commit
5852a7aabb
@ -59,7 +59,15 @@ rest_urlencoded() {
|
|||||||
if $onlydata; then
|
if $onlydata; then
|
||||||
data+=("--data-urlencode" "$item");
|
data+=("--data-urlencode" "$item");
|
||||||
else
|
else
|
||||||
data+=("$item")
|
# if argument is like "--header=<val>", then change to
|
||||||
|
# "--header <val>" because curl wants the latter
|
||||||
|
local arg="$(awk -F= '{print $1}' <<<"$item")"
|
||||||
|
local val="$(awk -F= '{print substr($0,length($1)+2)}' <<<"$item")"
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
data+=("$item")
|
||||||
|
else
|
||||||
|
data+=("$arg" "$val")
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
|
@ -29,6 +29,7 @@ create_user() {
|
|||||||
local email="$1"
|
local email="$1"
|
||||||
local pass="${2:-$email}"
|
local pass="${2:-$email}"
|
||||||
local priv="${3:-test}"
|
local priv="${3:-test}"
|
||||||
|
local totpVal="${4:-}" # "secret,token"
|
||||||
local localpart="$(awk -F@ '{print $1}' <<< "$email")"
|
local localpart="$(awk -F@ '{print $1}' <<< "$email")"
|
||||||
local domainpart="$(awk -F@ '{print $2}' <<< "$email")"
|
local domainpart="$(awk -F@ '{print $2}' <<< "$email")"
|
||||||
#local uid="$localpart"
|
#local uid="$localpart"
|
||||||
@ -39,19 +40,33 @@ create_user() {
|
|||||||
|
|
||||||
record "[create user $email ($dn)]"
|
record "[create user $email ($dn)]"
|
||||||
delete_dn "$dn"
|
delete_dn "$dn"
|
||||||
|
|
||||||
|
# totpSecret: base-32 digits (see RFC 4648), qty 32
|
||||||
|
# totpMruToken: base-10 digits, qty 6
|
||||||
|
# note: comma is not a base32 symbol
|
||||||
|
local totpObjectClass=""
|
||||||
|
local totpSecret="$(awk -F, '{print $1}' <<< "$totpVal")"
|
||||||
|
local totpMruToken="$(awk -F, '{print $2}' <<< "$totpVal")"
|
||||||
|
if [ ! -z "$totpVal" ]; then
|
||||||
|
local nl=$'\n'
|
||||||
|
totpObjectClass="${nl}objectClass: totpUser"
|
||||||
|
totpSecret="${nl}totpSecret: ${totpSecret}"
|
||||||
|
[ ! -z "$totpMruToken" ] && \
|
||||||
|
totpMruToken="${nl}totpMruToken: ${totpMruToken}"
|
||||||
|
fi
|
||||||
|
|
||||||
ldapadd -H "$LDAP_URL" -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD" >>$TEST_OF 2>&1 <<EOF
|
ldapadd -H "$LDAP_URL" -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD" >>$TEST_OF 2>&1 <<EOF
|
||||||
dn: $dn
|
dn: $dn
|
||||||
objectClass: inetOrgPerson
|
objectClass: inetOrgPerson
|
||||||
objectClass: mailUser
|
objectClass: mailUser
|
||||||
objectClass: shadowAccount
|
objectClass: shadowAccount${totpObjectClass}
|
||||||
uid: $uid
|
uid: $uid
|
||||||
cn: $localpart
|
cn: $localpart
|
||||||
sn: $localpart
|
sn: $localpart
|
||||||
displayName: $localpart
|
displayName: $localpart
|
||||||
mail: $email
|
mail: $email
|
||||||
maildrop: $email
|
maildrop: $email
|
||||||
mailaccess: $priv
|
mailaccess: $priv${totpSecret}${totpMruToken}
|
||||||
userPassword: $(slappasswd_hash "$pass")
|
userPassword: $(slappasswd_hash "$pass")
|
||||||
EOF
|
EOF
|
||||||
[ $? -ne 0 ] && die "Unable to add user $dn (as admin)"
|
[ $? -ne 0 ] && die "Unable to add user $dn (as admin)"
|
||||||
|
@ -49,6 +49,20 @@ mgmt_rest() {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgmt_rest_as_user() {
|
||||||
|
# Issue a REST call to the management subsystem
|
||||||
|
local verb="$1" # eg "POST"
|
||||||
|
local uri="$2" # eg "/mail/users/add"
|
||||||
|
local email="$3" # eg "alice@somedomain.com"
|
||||||
|
local pw="$4" # user's password
|
||||||
|
shift; shift; shift; shift # remaining arguments are data
|
||||||
|
|
||||||
|
# call function from lib/rest.sh
|
||||||
|
rest_urlencoded "$verb" "$uri" "${email}" "${pw}" "$@" >>$TEST_OF 2>&1
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mgmt_create_user() {
|
mgmt_create_user() {
|
||||||
local email="$1"
|
local email="$1"
|
||||||
@ -145,3 +159,195 @@ mgmt_assert_delete_alias_group() {
|
|||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mgmt_privileges_add() {
|
||||||
|
local user="$1"
|
||||||
|
local priv="$2" # only one privilege allowed
|
||||||
|
record "[add privilege '$priv' to $user]"
|
||||||
|
mgmt_rest POST "/admin/mail/users/privileges/add" "email=$user" "privilege=$priv"
|
||||||
|
rc=$?
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
mgmt_assert_privileges_add() {
|
||||||
|
if ! mgmt_privileges_add "$@"; then
|
||||||
|
test_failure "Unable to add privilege '$2' to $1"
|
||||||
|
test_failure "${REST_ERROR}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mgmt_get_totp_token() {
|
||||||
|
local secret="$1"
|
||||||
|
local mru_token="$2"
|
||||||
|
|
||||||
|
TOTP_TOKEN="" # this is set to the acquired token on success
|
||||||
|
|
||||||
|
# the user would normally give the secret to an authenticator app
|
||||||
|
# and get a token -- we'll do that out-of-band. we have to run
|
||||||
|
# the admin's python because setup does not do a 'pip install
|
||||||
|
# pyotp', so the system python3 probably won't have it
|
||||||
|
|
||||||
|
record "[Get the current token for the secret '$secret']"
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
|
||||||
|
while [ -z "$TOTP_TOKEN" -a $count -lt 10 ]; do
|
||||||
|
TOTP_TOKEN="$(/usr/local/lib/mailinabox/env/bin/python -c "import pyotp; totp=pyotp.TOTP(r'$secret'); print(totp.now());" 2>>"$TEST_OF")"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
record "Failed: Could not generate a TOTP token !"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TOTP_TOKEN" == "$mru_token" ]; then
|
||||||
|
TOTP_TOKEN=""
|
||||||
|
record "Waiting for unique token!"
|
||||||
|
sleep 5
|
||||||
|
else
|
||||||
|
record "Success: token is '$TOTP_TOKEN'"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
let count+=1
|
||||||
|
done
|
||||||
|
|
||||||
|
record "Failed: timeout !"
|
||||||
|
TOTP_TOKEN=""
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mgmt_totp_enable() {
|
||||||
|
# enable TOTP for user specified
|
||||||
|
# returns 0 if successful and TOTP_SECRET will contain the secret and TOTP_TOKEN will contain the token used
|
||||||
|
# returns 1 if a REST error occured. $REST_ERROR has the message
|
||||||
|
# returns 2 if some other error occured
|
||||||
|
#
|
||||||
|
|
||||||
|
local user="$1"
|
||||||
|
local pw="$2"
|
||||||
|
TOTP_SECRET=""
|
||||||
|
|
||||||
|
record "[Enable TOTP for $user]"
|
||||||
|
|
||||||
|
# 1. get a totp secret
|
||||||
|
if ! mgmt_rest_as_user "GET" "/admin/mfa/status" "$user" "$pw"; then
|
||||||
|
REST_ERROR="Failed: GET/admin/mfa/status: $REST_ERROR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOTP_SECRET="$(/usr/bin/jq -r ".totp_secret" <<<"$REST_OUTPUT")"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
record "Unable to obtain setup totp secret - is 'jq' installed?"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TOTP_SECRET" == "null" ]; then
|
||||||
|
record "No 'totp_secret' in the returned json !"
|
||||||
|
return 2
|
||||||
|
else
|
||||||
|
record "Found TOTP secret '$TOTP_SECRET'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! mgmt_get_totp_token "$TOTP_SECRET"; then
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. enable TOTP
|
||||||
|
record "Enabling TOTP using the secret and token"
|
||||||
|
if ! mgmt_rest_as_user "POST" "/admin/mfa/totp/enable" "$user" "$pw" "secret=$TOTP_SECRET" "token=$TOTP_TOKEN"; then
|
||||||
|
REST_ERROR="Failed: POST /admin/mfa/totp/enable: ${REST_ERROR}"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
record "Success: POST /mfa/totp/enable: '$REST_OUTPUT'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mgmt_assert_totp_enable() {
|
||||||
|
local user="$1"
|
||||||
|
mgmt_totp_enable "$@"
|
||||||
|
local code=$?
|
||||||
|
if [ $code -ne 0 ]; then
|
||||||
|
test_failure "Unable to enable TOTP for $user"
|
||||||
|
if [ $code -eq 1 ]; then
|
||||||
|
test_failure "${REST_ERROR}"
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
get_attribute "$LDAP_USERS_BASE" "(&(mail=$user)(objectClass=totpUser))" "dn"
|
||||||
|
if [ -z "$ATTR_DN" ]; then
|
||||||
|
test_failure "totpUser objectClass not present on $user"
|
||||||
|
fi
|
||||||
|
record_search "(mail=$user)"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mgmt_totp_disable() {
|
||||||
|
local user="$1"
|
||||||
|
local pw="$2"
|
||||||
|
record "[Disable TOTP for $user]"
|
||||||
|
if ! mgmt_rest_as_user "POST" "/admin/mfa/totp/disable" "$user" "$pw"
|
||||||
|
then
|
||||||
|
REST_ERROR="Failed: POST /admin/mfa/totp/disable: $REST_ERROR"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
record "Success"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mgmt_assert_totp_disable() {
|
||||||
|
local user="$1"
|
||||||
|
mgmt_totp_disable "$@"
|
||||||
|
local code=$?
|
||||||
|
if [ $code -ne 0 ]; then
|
||||||
|
test_failure "Unable to disable TOTP for $user: $REST_ERROR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
get_attribute "$LDAP_USERS_BASE" "(&(mail=$user)(objectClass=totpUser))" "dn"
|
||||||
|
if [ ! -z "$ATTR_DN" ]; then
|
||||||
|
test_failure "totpUser objectClass still present on $user"
|
||||||
|
fi
|
||||||
|
record_search "(mail=$user)"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mgmt_assert_admin_me() {
|
||||||
|
local user="$1"
|
||||||
|
local pw="$2"
|
||||||
|
local expected_status="${3:-ok}"
|
||||||
|
shift; shift; shift; # remaining arguments are data
|
||||||
|
|
||||||
|
# note: GET /admin/me always returns http status 200, but errors are in
|
||||||
|
# the json payload
|
||||||
|
record "[Get /admin/me as $user]"
|
||||||
|
if ! mgmt_rest_as_user "GET" "/admin/me" "$user" "$pw" "$@"; then
|
||||||
|
test_failure "GET /admin/me as $user failed: $REST_ERROR"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
else
|
||||||
|
local status code
|
||||||
|
status="$(/usr/bin/jq -r '.status' <<<"$REST_OUTPUT")"
|
||||||
|
code=$?
|
||||||
|
if [ $code -ne 0 ]; then
|
||||||
|
test_failure "Unable to run jq ($code) on /admin/me json"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
elif [ "$status" == "null" ]; then
|
||||||
|
test_failure "No 'status' in /admin/me json"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
elif [ "$status" != "$expected_status" ]; then
|
||||||
|
test_failure "Expected a login status of '$expected_status', but got '$status'"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
@ -3,14 +3,16 @@
|
|||||||
# Access assertions:
|
# Access assertions:
|
||||||
# service accounts, except management:
|
# service accounts, except management:
|
||||||
# can bind but not change passwords, including their own
|
# can bind but not change passwords, including their own
|
||||||
# can read all attributes of all users but not userPassword
|
# can read all attributes of all users but not userPassword, totpSecret, totpMruToken
|
||||||
# can not write any user attributes, include shadowLastChange
|
# can not write any user attributes, including shadowLastChange
|
||||||
# can read config subtree (permitted-senders, domains)
|
# can read config subtree (permitted-senders, domains)
|
||||||
# no access to services subtree, except their own dn
|
# no access to services subtree, except their own dn
|
||||||
# users:
|
# users:
|
||||||
# can bind and change their own password
|
# can bind and change their own password
|
||||||
# can read and change their own shadowLastChange
|
# can read and change their own shadowLastChange
|
||||||
# can read attributess of all users except mailaccess
|
# no read or write access to user's own totpSecret or totpMruToken
|
||||||
|
# can read attributess of all users except:
|
||||||
|
# mailaccess, totpSecret, totpMruToken
|
||||||
# no access to config subtree
|
# no access to config subtree
|
||||||
# no access to services subtree
|
# no access to services subtree
|
||||||
# other:
|
# other:
|
||||||
@ -36,19 +38,24 @@ test_user_change_password() {
|
|||||||
|
|
||||||
|
|
||||||
test_user_access() {
|
test_user_access() {
|
||||||
# 1. can read attributess of all users except mailaccess
|
# 1. can read attributess of all users except mailaccess, totpSecret, totpMruToken
|
||||||
# 2. can read and change their own shadowLastChange
|
# 2. can read and change their own shadowLastChange
|
||||||
# 3. no access to config subtree
|
# 3. no access to config subtree
|
||||||
# 4. no access to services subtree
|
# 4. no access to services subtree
|
||||||
|
# 5. no read or write access to own totpSecret or totpMruToken
|
||||||
|
|
||||||
test_start "user-access"
|
test_start "user-access"
|
||||||
|
|
||||||
|
local totpSecret="12345678901234567890"
|
||||||
|
local totpMruToken="94287082"
|
||||||
|
|
||||||
# create regular user's alice and bob
|
# create regular user's alice and bob
|
||||||
local alice="alice@somedomain.com"
|
local alice="alice@somedomain.com"
|
||||||
create_user "alice@somedomain.com" "alice"
|
create_user "alice@somedomain.com" "alice" "" "$totpSecret,$totpMruToken"
|
||||||
local alice_dn="$ATTR_DN"
|
local alice_dn="$ATTR_DN"
|
||||||
|
|
||||||
local bob="bob@somedomain.com"
|
local bob="bob@somedomain.com"
|
||||||
create_user "bob@somedomain.com" "bob"
|
create_user "bob@somedomain.com" "bob" "" "$totpSecret,$totpMruToken"
|
||||||
local bob_dn="$ATTR_DN"
|
local bob_dn="$ATTR_DN"
|
||||||
|
|
||||||
# alice should be able to set her own shadowLastChange
|
# alice should be able to set her own shadowLastChange
|
||||||
@ -56,19 +63,29 @@ test_user_access() {
|
|||||||
|
|
||||||
# test that alice can read her own attributes
|
# test that alice can read her own attributes
|
||||||
assert_r_access "$alice_dn" "$alice_dn" "alice" read mail maildrop cn sn shadowLastChange
|
assert_r_access "$alice_dn" "$alice_dn" "alice" read mail maildrop cn sn shadowLastChange
|
||||||
# alice should not have access to her own mailaccess, though
|
|
||||||
assert_r_access "$alice_dn" "$alice_dn" "alice" no-read mailaccess
|
# alice should not have access to her own mailaccess, totpSecret or totpMruToken, though
|
||||||
|
assert_r_access "$alice_dn" "$alice_dn" "alice" no-read mailaccess totpSecret totpMruToken
|
||||||
|
|
||||||
# test that alice cannot change her own select attributes
|
# test that alice cannot change her own select attributes
|
||||||
assert_w_access "$alice_dn" "$alice_dn" "alice"
|
assert_w_access "$alice_dn" "$alice_dn" "alice"
|
||||||
|
|
||||||
|
# test that alice cannot change her own totpSecret or totpMruToken
|
||||||
|
assert_w_access "$alice_dn" "$alice_dn" "alice" no-write "totpSecret=ABC" "totpMruToken=123456"
|
||||||
|
|
||||||
|
|
||||||
# test that alice can read bob's attributes
|
# test that alice can read bob's attributes
|
||||||
assert_r_access "$bob_dn" "$alice_dn" "alice" read mail maildrop cn sn
|
assert_r_access "$bob_dn" "$alice_dn" "alice" read mail maildrop cn sn
|
||||||
# alice does not have access to bob's mailaccess though
|
|
||||||
assert_r_access "$bob_dn" "$alice_dn" "alice" no-read mailaccess
|
# alice should not have access to bob's mailaccess, totpSecret, or totpMruToken
|
||||||
# test that alice cannot change bob's attributes
|
assert_r_access "$bob_dn" "$alice_dn" "alice" no-read mailaccess totpSecret totpMruToken
|
||||||
|
|
||||||
|
# test that alice cannot change bob's select attributes
|
||||||
assert_w_access "$bob_dn" "$alice_dn" "alice"
|
assert_w_access "$bob_dn" "$alice_dn" "alice"
|
||||||
|
|
||||||
|
# test that alice cannot change bob's attributes
|
||||||
|
assert_w_access "$bob_dn" "$alice_dn" "alice" no-write "totpSecret=ABC" "totpMruToken=123456"
|
||||||
|
|
||||||
|
|
||||||
# test that alice cannot read a service account's attributes
|
# test that alice cannot read a service account's attributes
|
||||||
assert_r_access "$LDAP_POSTFIX_DN" "$alice_dn" "alice"
|
assert_r_access "$LDAP_POSTFIX_DN" "$alice_dn" "alice"
|
||||||
@ -132,9 +149,12 @@ test_service_access() {
|
|||||||
|
|
||||||
test_start "service-access"
|
test_start "service-access"
|
||||||
|
|
||||||
|
local totpSecret="12345678901234567890"
|
||||||
|
local totpMruToken="94287082"
|
||||||
|
|
||||||
# create regular user with password "alice"
|
# create regular user with password "alice"
|
||||||
local alice="alice@somedomain.com"
|
local alice="alice@somedomain.com"
|
||||||
create_user "alice@somedomain.com" "alice"
|
create_user "alice@somedomain.com" "alice" "" "$totpSecret,$totpMruToken"
|
||||||
|
|
||||||
# create a test service account
|
# create a test service account
|
||||||
create_service_account "test" "test"
|
create_service_account "test" "test"
|
||||||
@ -154,12 +174,12 @@ test_service_access() {
|
|||||||
# check that service account can read user attributes
|
# check that service account can read user attributes
|
||||||
assert_r_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" read mail maildrop uid cn sn shadowLastChange
|
assert_r_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" read mail maildrop uid cn sn shadowLastChange
|
||||||
|
|
||||||
# service account should not be able to read user's userPassword
|
# service account should not be able to read user's userPassword, totpSecret or totpMruToken
|
||||||
assert_r_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" no-read userPassword
|
assert_r_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" no-read userPassword totpSecret totpMruToken
|
||||||
|
|
||||||
# service accounts cannot change user attributes
|
# service accounts cannot change user attributes
|
||||||
assert_w_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD"
|
assert_w_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD"
|
||||||
assert_w_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" no-write "shadowLastChange=1"
|
assert_w_access "$alice_dn" "$LDAP_POSTFIX_DN" "$LDAP_POSTFIX_PASSWORD" no-write "shadowLastChange=1" "totpSecret=ABC" "totpMruToken=333333"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# service accounts can read config subtree (permitted-senders, domains)
|
# service accounts can read config subtree (permitted-senders, domains)
|
||||||
|
@ -200,8 +200,88 @@ test_intl_domains() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test_totp() {
|
||||||
|
test_start "totp"
|
||||||
|
|
||||||
|
# local intl alias
|
||||||
|
local alice="alice@somedomain.com"
|
||||||
|
local alice_pw="$(generate_password 16)"
|
||||||
|
|
||||||
|
start_log_capture
|
||||||
|
|
||||||
|
# create alice
|
||||||
|
mgmt_assert_create_user "$alice" "$alice_pw"
|
||||||
|
|
||||||
|
# alice must be admin to use TOTP
|
||||||
|
if ! have_test_failures; then
|
||||||
|
mgmt_assert_privileges_add "$alice" "admin"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add totp to alice's account (if successful, secret is in TOTP_SECRET)
|
||||||
|
if ! have_test_failures; then
|
||||||
|
mgmt_assert_totp_enable "$alice" "$alice_pw"
|
||||||
|
# TOTP_SECRET and TOTP_TOKEN are now set...
|
||||||
|
fi
|
||||||
|
|
||||||
|
# logging in with just the password should now fail
|
||||||
|
if ! have_test_failures; then
|
||||||
|
record "Expect a login failure..."
|
||||||
|
mgmt_assert_admin_me "$alice" "$alice_pw" "missing_token"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# logging into /admin/me with a password and a token should
|
||||||
|
# succeed, and an api_key generated
|
||||||
|
local api_key
|
||||||
|
if ! have_test_failures; then
|
||||||
|
record "Try using a password and a token to get the user api key, we may have to wait 30 seconds to get a new token..."
|
||||||
|
|
||||||
|
local old_totp_token="$TOTP_TOKEN"
|
||||||
|
if ! mgmt_get_totp_token "$TOTP_SECRET" "$TOTP_TOKEN"; then
|
||||||
|
test_failure "Could not obtain a new TOTP token"
|
||||||
|
|
||||||
|
else
|
||||||
|
# we have a new token, try logging in ...
|
||||||
|
# the token must be placed in the header "x-auth-token"
|
||||||
|
if mgmt_assert_admin_me "$alice" "$alice_pw" "ok" "--header=x-auth-token: $TOTP_TOKEN"
|
||||||
|
then
|
||||||
|
api_key="$(/usr/bin/jq -r '.api_key' <<<"$REST_OUTPUT")"
|
||||||
|
record "Success: login with TOTP token successful. api_key=$api_key"
|
||||||
|
|
||||||
|
# ensure the totpMruToken was changed in LDAP
|
||||||
|
get_attribute "$LDAP_USERS_BASE" "(mail=$alice)" "totpMruToken"
|
||||||
|
if [ "$ATTR_VALUE" != "$TOTP_TOKEN" ]; then
|
||||||
|
record_search "(mail=$alice)"
|
||||||
|
test_failure "totpMruToken wasn't updated in LDAP"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# we should be able to login using the user's api key
|
||||||
|
if ! have_test_failures; then
|
||||||
|
record "Login using the user's api key"
|
||||||
|
mgmt_assert_admin_me "$alice" "$api_key" "ok"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# disable totp on the account - login should work with just the password
|
||||||
|
# and the ldap entry should not have the 'totpUser' objectClass
|
||||||
|
if ! have_test_failures; then
|
||||||
|
if mgmt_assert_totp_disable "$alice" "$api_key"; then
|
||||||
|
mgmt_assert_admin_me "$alice" "$alice_pw" "ok"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
mgmt_assert_delete_user "$alice"
|
||||||
|
test_end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
suite_start "management-users" mgmt_start
|
suite_start "management-users" mgmt_start
|
||||||
|
|
||||||
|
test_totp
|
||||||
test_mixed_case_domains
|
test_mixed_case_domains
|
||||||
test_mixed_case_users
|
test_mixed_case_users
|
||||||
test_intl_domains
|
test_intl_domains
|
||||||
|
@ -118,8 +118,9 @@ init_miab_testing() {
|
|||||||
|
|
||||||
# python3-dnspython: is used by the python scripts in 'tests' and is
|
# python3-dnspython: is used by the python scripts in 'tests' and is
|
||||||
# not installed by setup
|
# not installed by setup
|
||||||
|
# also install 'jq' for json processing
|
||||||
wait_for_apt
|
wait_for_apt
|
||||||
apt-get install -y -qq python3-dnspython
|
apt-get install -y -qq python3-dnspython jq
|
||||||
|
|
||||||
# copy in pre-built MiaB-LDAP ssl files
|
# copy in pre-built MiaB-LDAP ssl files
|
||||||
# 1. avoid the lengthy generation of DH params
|
# 1. avoid the lengthy generation of DH params
|
||||||
|
Loading…
Reference in New Issue
Block a user