140 lines
3.5 KiB
Bash
Executable File
140 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
set -uo pipefail
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") [options] <app-name>
|
|
Options:
|
|
-c, --config <path> Write JSON config to file (optional)
|
|
-h, --help Show this help message and exit
|
|
EOF
|
|
}
|
|
|
|
CONFIG_PATH=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-c|--config)
|
|
if [[ $# -le 0 ]]; then
|
|
echo "Error: Missing value for --config" >&2
|
|
exit 1
|
|
fi
|
|
CONFIG_PATH="$2"
|
|
shift 2
|
|
;;
|
|
-*)
|
|
echo "Error: Unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
APP_NAME="${1:-}"
|
|
if [[ -z "$APP_NAME" ]]; then
|
|
echo "Error: Application name is required." >&2
|
|
usage >&2
|
|
exit 1
|
|
fi
|
|
|
|
APP_ID="$(az ad app list --display-name "$APP_NAME" | jq -r '[.[].appId] | join(",")')"
|
|
if [[ "$APP_ID" =~ "," ]]; then
|
|
echo "Error: The application name '$APP_NAME' is not unique." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "$APP_ID" ]]; then
|
|
APP_ID="$(az ad app create --display-name "$APP_NAME" --query appId -o tsv)"
|
|
if [[ -z "$APP_ID" ]]; then
|
|
echo "Error: Failed to create application '$APP_NAME'." >&2
|
|
exit 1
|
|
fi
|
|
echo "Created application '$APP_NAME' with appId '$APP_ID'."
|
|
else
|
|
printf "Application '%s' already exists. Update it? [y/N]: " "$APP_NAME" >&2
|
|
read -r ANSWER
|
|
if [[ ! "$ANSWER" =~ ^[Yy]([Ee][Ss])*$ ]]; then
|
|
echo "Canceled." >&2
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
RESOURCE_ACCESS='[
|
|
{
|
|
"resourceAppId": "00000003-0000-0000-c000-000000000000",
|
|
"resourceAccess": [
|
|
{ "id": "0e263e50-5827-48a4-b97c-d940288653c7", "type": "Scope" }
|
|
]
|
|
},
|
|
{
|
|
"resourceAppId": "499b84ac-1321-427f-aa17-267ca6975798",
|
|
"resourceAccess": [
|
|
{ "id": "ee69721e-6c3a-468f-a9ec-302d16a4c599", "type": "Scope" }
|
|
]
|
|
},
|
|
{
|
|
"resourceAppId": "797f4846-ba00-4fd7-ba43-dac1f8f63013",
|
|
"resourceAccess": [
|
|
{ "id": "41094075-9dad-400e-a0bd-54e686782033", "type": "Scope" }
|
|
]
|
|
}
|
|
]'
|
|
|
|
if ! az ad app update \
|
|
--id "$APP_ID" \
|
|
--sign-in-audience AzureADMyOrg \
|
|
--is-fallback-public-client true \
|
|
--required-resource-accesses "$RESOURCE_ACCESS" \
|
|
--public-client-redirect-uris http://localhost "msal${APP_ID}://auth" \
|
|
--enable-access-token-issuance true \
|
|
--enable-id-token-issuance true \
|
|
>/dev/null 2>&1; then
|
|
echo "Error: Failed to configure application '$APP_NAME' ($APP_ID)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
SP_ID="$(az ad sp show --id "$APP_ID" --query id -o tsv)"
|
|
if [[ -z "$SP_ID" ]]; then
|
|
SP_ID="$(az ad sp create --id "$APP_ID" --query id -o tsv)"
|
|
if [[ -z "$SP_ID" ]]; then
|
|
echo "Error: Failed to create service principal for application '$APP_NAME' ($APP_ID)." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Service principal for application '$APP_NAME' already exists with id '$SP_ID'."
|
|
fi
|
|
|
|
az ad app permission admin-consent --id "$APP_ID"
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Error: Failed to grant admin consent for application '$APP_NAME' ($APP_ID)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
TENANT_ID="$(az account show --query tenantId -o tsv)"
|
|
if [[ -z "$TENANT_ID" ]]; then
|
|
echo "Error: Failed to resolve tenantId from current Azure CLI context." >&2
|
|
exit 1
|
|
fi
|
|
|
|
CONFIG="{
|
|
\"tenantId\": \"$TENANT_ID\",
|
|
\"clientId\": \"$APP_ID\"
|
|
}
|
|
"
|
|
|
|
if [[ -n "$CONFIG_PATH" ]]; then
|
|
mkdir -p "$(dirname "$CONFIG_PATH")"
|
|
else
|
|
CONFIG_PATH="/dev/null"
|
|
fi
|
|
|
|
echo "$CONFIG" | tee "$CONFIG_PATH"
|