#!/bin/bash
set -e

# Creates the Azure app registrations required by Glasswall Halo.
# By default both the Portal (portal-access + portal-client) and the API
# (api-access) registrations are created. Use the flags below to skip either.

usage() {
    echo "Usage: $0 [--skip-portal] [--skip-api] <portal_domain> [suffix]"
    echo ""
    echo "  By default both the Portal and API app registrations are created."
    echo ""
    echo "  --skip-portal    Do not create the portal-access/portal-client registrations"
    echo "  --skip-api       Do not create the api-access registration"
    echo "  <portal_domain>  Domain to use for the Portal (required unless --skip-portal)"
    echo "  [suffix]         Optional suffix for app registration names and identifier URIs"
}

setup_portal=true
setup_api=true
positional=()

while [[ "$#" -gt 0 ]]; do
    case "$1" in
        --skip-portal)
            setup_portal=false
            shift
            ;;
        --skip-api)
            setup_api=false
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            positional+=("$1")
            shift
            ;;
    esac
done

if [[ "$setup_portal" == false && "$setup_api" == false ]]; then
    echo "Nothing to do: both --skip-portal and --skip-api were specified"
    usage
    exit 1
fi

# When the Portal is being set up the first positional argument is the domain;
# otherwise (API only) the first positional argument is the optional suffix.
if [[ "$setup_portal" == true ]]; then
    portal_domain="${positional[0]}"
    suffix="${positional[1]}"
    if [[ -z "$portal_domain" ]]; then
        echo "Please pass the domain name to use for the Portal and an optional suffix"
        usage
        exit 1
    fi
else
    suffix="${positional[0]}"
fi

tenant_id=$(az account show --query tenantId -o tsv)

if [[ "$setup_api" == true ]]; then
    # API Access app registration
    tee > api-access-required-resource.json <<EOF
[{
    "resourceAppId": "00000003-0000-0000-c000-000000000000",
    "resourceAccess": [
        {
            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
            "type": "Scope"
        }
    ]
}]
EOF

    tee > api-access-app-roles.json <<EOF
[{
    "allowedMemberTypes": [
        "Application",
        "User"
    ],
    "description": "Admins can manage anything on the Halo",
    "displayName": "Admin",
    "isEnabled": "true",
    "value": "Admin"
},
{
    "allowedMemberTypes": [
        "Application",
        "User"
    ],
    "description": "Users can read policies and rebuild files",
    "displayName": "User",
    "isEnabled": "true",
    "value": "User"
}]
EOF
    api_access_response=$(az ad app create --display-name ar-halo-api-access${suffix} --identifier-uris "api://${tenant_id}/cdrplatform-api-access${suffix}" \
    --required-resource-accesses @api-access-required-resource.json --app-roles @api-access-app-roles.json \
     --sign-in-audience AzureADMyOrg)
    echo "created api access app registration"
    api_access_client_id=$(echo "$api_access_response" | jq -r ".id")
    az ad sp create --id "${api_access_client_id}" -o none
    echo "created API access Service Principal"
    rm -f api-access-required-resource.json
    rm -f api-access-app-roles.json
fi

if [[ "$setup_portal" == true ]]; then
    # Portal Access app registration
    tee > portal-access-required-resource.json <<EOF
[{
    "resourceAppId": "00000003-0000-0000-c000-000000000000",
    "resourceAccess": [
        {
            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
            "type": "Scope"
        }
    ]
}]
EOF

    tee > portal-access-app-roles.json <<EOF
[{
    "allowedMemberTypes": [
        "Application",
        "User"
    ],
    "description": "Admins can manage anything on the Halo",
    "displayName": "Admin",
    "isEnabled": "true",
    "value": "Admin"
},
{
    "allowedMemberTypes": [
        "Application",
        "User"
    ],
    "description": "Users can read policies and rebuild files",
    "displayName": "User",
    "isEnabled": "true",
    "value": "User"
}]
EOF
    uuid=$(uuidgen)

    tee > oauth2-permissions.json <<EOF
{
    "acceptMappedClaims": null,
    "knownClientApplications": [],
    "oauth2PermissionScopes": [
        {
            "adminConsentDescription": "Allow the application to access example on behalf of the signed-in user.",
            "adminConsentDisplayName": "PortalUserScope",
            "id": "$uuid",
            "isEnabled": true,
            "type": "User",
            "userConsentDescription": null,
            "userConsentDisplayName": null,
            "value": "PortalUserScope"
        }
    ]
}
EOF

    portal_access_response=$(az ad app create --display-name ar-halo-portal-access${suffix} --identifier-uris "api://${tenant_id}/cdrplatform-portal-access${suffix}" \
    --required-resource-accesses @portal-access-required-resource.json --app-roles @portal-access-app-roles.json \
     --sign-in-audience AzureADMyOrg)
    echo "created portal access app registration"
    portal_app_id=$(echo "$portal_access_response" | jq -r ".appId")
    portal_id=$(echo "$portal_access_response" | jq -r ".id")
    echo "portal_access_id is $portal_id"

    az ad app update --id "$portal_app_id" --set api=@oauth2-permissions.json
    az ad sp create --id "${portal_id}" -o none
    echo "created portal access Service Principal"

    rm -f portal-access-required-resource.json
    rm -f portal-access-app-roles.json
    rm -f oauth2-permissions.json

    # Portal Client app registration
    tee > portal-client-required-resource.json <<EOF
[{
    "resourceAppId": "00000003-0000-0000-c000-000000000000",
    "resourceAccess": [
        {
            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
            "type": "Scope"
        }
    ]
},
{
    "resourceAppId": "${portal_app_id}",
    "resourceAccess": [
        {
            "id": "${uuid}",
            "type": "Scope"
        }
    ]
}
]
EOF

    portal_client_response=$(az ad app create --display-name ar-halo-portal-client${suffix} --identifier-uris "api://${tenant_id}/cdrplatform-portal-client${suffix}" \
    --required-resource-accesses @portal-client-required-resource.json --web-redirect-uris "https://${portal_domain}/authentication/login-callback" --enable-access-token-issuance true \
     --sign-in-audience AzureADMyOrg)
    echo "created portal app reg"
    portal_client_app_id=$(echo "$portal_client_response" | jq -r ".appId")
    portal_client_id=$(echo "$portal_client_response" | jq -r ".id")

    body="{\"web\":{\"logoutUrl\":\"https://${portal_domain}/authentication/logout\"},\"spa\":{\"redirectUris\":[\"https://${portal_domain}/authentication/login-callback\"]}}"
    az rest --method PATCH --uri "https://graph.microsoft.com/v1.0/applications/${portal_client_id}" --headers 'Content-Type=application/json' --body "$body"
    echo "patched portal"
    az ad sp create --id "${portal_client_id}" -o none
    echo "created portal Service Principal"

    rm -f portal-client-required-resource.json
    rm -f portal-client-app-roles.json
fi

echo "Please make a note of below values:"
echo "tenant_id is ${tenant_id}"
if [[ "$setup_portal" == true ]]; then
    echo "portal_client_id is ${portal_client_app_id}"
    echo "portal client uri is api://${tenant_id}/cdrplatform-portal-client${suffix}"
    echo "portal access uri is api://${tenant_id}/cdrplatform-portal-access${suffix}"
fi
if [[ "$setup_api" == true ]]; then
    echo "api access uri is api://${tenant_id}/cdrplatform-api-access${suffix}"
fi
