2023-01-19 17:18:05 +00:00
#!/usr/bin/env bash
function error_handler() {
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
exit "$2"
}
trap 'error_handler ${LINENO} $?' ERR
set -o errtrace -o errexit -o nounset -o pipefail
2023-02-03 17:51:57 +00:00
# you can get a list of users from the keycloak realm file like:
# grep '"email" :' keycloak/realm_exports/spiffworkflow-realm.json | awk -F : '{print $2}' | sed -E 's/ "//g' | sed -E 's/",//g' > s
# we keep some of these in keycloak/test_user_lists
# spiffworkflow-realm.json is a mashup of the status and sartography user lists.
2023-01-19 17:18:05 +00:00
user_file_with_one_email_per_line="${1:-}"
2023-02-03 17:51:57 +00:00
2023-01-19 19:54:39 +00:00
keycloak_realm="${2:-spiffworkflow}"
2023-01-19 17:18:05 +00:00
if [[ -z "${1:-}" ]]; then
>&2 echo "usage: $(basename "$0") [user_file_with_one_email_per_line]"
exit 1
fi
2023-02-13 21:16:43 +00:00
if [[ -z "${KEYCLOAK_BASE_URL:-}" ]]; then
KEYCLOAK_BASE_URL=http://localhost:7002
fi
2023-02-24 15:41:57 +00:00
if [[ -z "${ADMIN_USERNAME:-}" ]]; then
ADMIN_USERNAME="admin"
fi
if [[ -z "${ADMIN_PASSWORD:-}" ]]; then
ADMIN_PASSWORD="admin"
fi
2023-02-13 21:16:43 +00:00
2023-02-13 21:04:57 +00:00
REALM_NAME="$keycloak_realm"
2023-01-19 17:18:05 +00:00
SECURE=false
KEYCLOAK_URL=$KEYCLOAK_BASE_URL/realms/$REALM_NAME/protocol/openid-connect/token
if [[ $SECURE = 'y' ]]; then
INSECURE=
else
INSECURE=--insecure
fi
# https://www.appsdeveloperblog.com/keycloak-rest-api-create-a-new-user/
result=$(curl --fail -s -X POST "$KEYCLOAK_URL" "$INSECURE" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "username=${ADMIN_USERNAME}" \
--data-urlencode "password=${ADMIN_PASSWORD}" \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=admin-cli'
)
backend_token=$(jq -r '.access_token' <<< "$result")
2023-02-06 20:34:55 +00:00
function add_user() {
local user_email=$1
local username=$2
2023-03-30 21:19:37 +00:00
local pass=$3
local user_attribute_one=$4
2023-02-06 20:34:55 +00:00
2023-03-30 21:19:37 +00:00
local credentials='{"type":"password","value":"'"${pass}"'","temporary":false}'
2023-02-06 20:34:55 +00:00
local data='{"email":"'"${user_email}"'", "enabled":"true", "username":"'"${username}"'", "credentials":['"${credentials}"']'
if [[ -n "$user_attribute_one" ]]; then
data=''${data}', "attributes": {"'${custom_attribute_one}'": [ "'$user_attribute_one'" ]}'
fi
data="${data}}"
local http_code
2023-02-13 21:04:57 +00:00
http_code=$(curl --silent -o /dev/null -w '%{http_code}' --location --request POST "${KEYCLOAK_BASE_URL}/admin/realms/${keycloak_realm}/users" \
2023-02-06 20:34:55 +00:00
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $backend_token" \
--data-raw "$data")
echo "$http_code"
}
first_line_processed="false"
custom_attribute_one=''
while read -r input_line; do
if ! grep -qE '^#' <<<"$input_line" ; then
if [[ "$first_line_processed" == "false" ]]; then
email_header=$(awk -F ',' '{print $1}' <<<"$input_line")
2023-03-30 21:19:37 +00:00
pass_header=$(awk -F ',' '{print $2}' <<<"$input_line")
2023-02-06 20:34:55 +00:00
if [[ "$email_header" != "email" ]]; then
>&2 echo "ERROR: the first column in the first row must be email."
exit 1
fi
2023-03-30 21:19:37 +00:00
if [[ "$pass_header" != "pass" ]]; then
>&2 echo "ERROR: the first column in the first row must be pass."
exit 1
fi
custom_attribute_one=$(awk -F ',' '{print $3}' <<<"$input_line")
2023-02-06 20:34:55 +00:00
first_line_processed="true"
elif [[ -n "$input_line" ]]; then
2023-03-09 15:59:20 +00:00
echo "Importing: $input_line"
2023-02-06 20:34:55 +00:00
user_email=$(awk -F ',' '{print $1}' <<<"$input_line")
username=$(awk -F '@' '{print $1}' <<<"$user_email")
2023-03-27 18:09:08 +00:00
if [[ "$username" == "$ADMIN_USERNAME" || "$user_email" == "$ADMIN_USERNAME" ]]; then
>&2 echo "ERROR: The user used as the admin user matches a user in the current import list. This should not happen. Comment out that user from the list or use a different admin user: ${ADMIN_USERNAME}"
exit 1
fi
2023-03-30 21:19:37 +00:00
password=$(awk -F ',' '{print $2}' <<<"$input_line")
echo "Password: $password"
user_attribute_one=$(awk -F ',' '{print $3}' <<<"$input_line")
http_code=$(add_user "$user_email" "$username" "$password" "$user_attribute_one")
2023-02-06 20:34:55 +00:00
if [[ "$http_code" == "409" ]]; then
2023-02-13 21:04:57 +00:00
user_info=$(curl --fail --silent --location --request GET "${KEYCLOAK_BASE_URL}/admin/realms/${keycloak_realm}/users?username=${username}&exact=true" \
2023-02-06 20:34:55 +00:00
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $backend_token")
user_id=$(jq -r '.[0] | .id' <<<"$user_info")
if [[ -z "$user_id" ]]; then
>&2 echo "ERROR: Could not find user_id for user: ${user_email}"
exit 1
fi
2023-02-13 21:04:57 +00:00
curl --fail --location --silent --request DELETE "${KEYCLOAK_BASE_URL}/admin/realms/${keycloak_realm}/users/${user_id}" \
2023-02-06 20:34:55 +00:00
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $backend_token"
2023-03-30 21:19:37 +00:00
http_code=$(add_user "$user_email" "$username" "$password" "$user_attribute_one")
2023-02-13 21:04:57 +00:00
fi
if [[ "$http_code" != "201" ]]; then
>&2 echo "ERROR: Failed to create user: ${user_email} with http_code: ${http_code}"
exit 1
2023-02-06 20:34:55 +00:00
fi
fi
2023-01-19 17:18:05 +00:00
fi
done <"$user_file_with_one_email_per_line"