#!/bin/bash
###############################################################################
# Smarter Visitor Registration - Grant Microsoft Graph permissions
###############################################################################
# Run AFTER the deployment (Azure Marketplace, portal or template):
#   1. Assigns the Microsoft Graph application roles Group.Read.All and
#      User.Read.All to the web app's user-assigned managed identity
#      (<deployment-prefix>-identity). The backend uses them for admin-group
#      checks, the user and group pickers and Teams call targets.
#   2. Grants tenant-wide admin consent for the delegated permissions of the
#      app registration, so visitors receive e-mails and users see no consent
#      prompt. Equivalent to "Grant admin consent" in the Entra admin centre.
#
# Marketplace and portal deployments cannot do this inside the template
# (Microsoft Graph Bicep resources are only supported from Azure CLI/PowerShell).
#
# Usage: ./grant-graph-permissions.sh <resource-group> <deployment-prefix> [client-id]
#
# Example:
#   ./grant-graph-permissions.sh rg-visitor-registration visitorreg 11111111-2222-3333-4444-555555555555
#
# Requirements: Azure CLI, signed in with an account that may assign Graph
# application roles and grant admin consent (Privileged Role Administrator or
# Global Administrator).
###############################################################################

set -euo pipefail

RESOURCE_GROUP="${1:-}"
DEPLOYMENT_NAME="${2:-}"
CLIENT_ID="${3:-}"

if [ -z "$RESOURCE_GROUP" ] || [ -z "$DEPLOYMENT_NAME" ]; then
    echo "Usage: $0 <resource-group> <deployment-prefix> [client-id]" >&2
    exit 1
fi

GRAPH="https://graph.microsoft.com/v1.0"
GRAPH_APP_ID="00000003-0000-0000-c000-000000000000"
IDENTITY_NAME="${DEPLOYMENT_NAME}-identity"

# Microsoft Graph service principal in this tenant
GRAPH_SP_ID=$(az ad sp show --id "$GRAPH_APP_ID" --query id -o tsv)

# Managed identity of the web app
PRINCIPAL_ID=$(az identity show --resource-group "$RESOURCE_GROUP" --name "$IDENTITY_NAME" --query principalId -o tsv)
echo "Managed identity: ${IDENTITY_NAME} (${PRINCIPAL_ID})"

ASSIGNED=$(az rest --method GET --uri "${GRAPH}/servicePrincipals/${PRINCIPAL_ID}/appRoleAssignments" --query "value[].appRoleId" -o tsv 2>/dev/null || true)

grant_role() {
    local role_id="$1" role_name="$2"
    if echo "$ASSIGNED" | grep -qi "$role_id"; then
        echo "  ${role_name}: already assigned"
        return
    fi
    az rest --method POST --uri "${GRAPH}/servicePrincipals/${GRAPH_SP_ID}/appRoleAssignedTo" \
        --headers "Content-Type=application/json" \
        --body "{\"principalId\":\"${PRINCIPAL_ID}\",\"resourceId\":\"${GRAPH_SP_ID}\",\"appRoleId\":\"${role_id}\"}" \
        --output none
    echo "  ${role_name}: assigned"
}

echo "Assigning Microsoft Graph application roles ..."
grant_role "5b567255-7703-4780-807c-7be8301ae99b" "Group.Read.All"
grant_role "df021288-bdef-4463-88db-98f22de89214" "User.Read.All"

if [ -n "$CLIENT_ID" ]; then
    echo ""
    echo "Granting admin consent for the app registration ${CLIENT_ID} ..."
    APP_SP_ID=$(az ad sp show --id "$CLIENT_ID" --query id -o tsv 2>/dev/null || true)
    if [ -z "$APP_SP_ID" ]; then
        az ad sp create --id "$CLIENT_ID" --output none
        APP_SP_ID=$(az ad sp show --id "$CLIENT_ID" --query id -o tsv)
    fi
    SCOPES="User.Read User.ReadBasic.All Group.Read.All People.Read Mail.Send"
    EXISTING_GRANT=$(az rest --method GET --uri "${GRAPH}/oauth2PermissionGrants?\$filter=clientId eq '${APP_SP_ID}' and consentType eq 'AllPrincipals'" --query "value[?resourceId=='${GRAPH_SP_ID}'].id | [0]" -o tsv 2>/dev/null || true)
    if [ -n "$EXISTING_GRANT" ]; then
        az rest --method PATCH --uri "${GRAPH}/oauth2PermissionGrants/${EXISTING_GRANT}" \
            --headers "Content-Type=application/json" --body "{\"scope\":\"${SCOPES}\"}" --output none
        echo "  admin consent updated"
    else
        az rest --method POST --uri "${GRAPH}/oauth2PermissionGrants" \
            --headers "Content-Type=application/json" \
            --body "{\"clientId\":\"${APP_SP_ID}\",\"consentType\":\"AllPrincipals\",\"resourceId\":\"${GRAPH_SP_ID}\",\"scope\":\"${SCOPES}\"}" \
            --output none
        echo "  admin consent granted"
    fi
fi

echo ""
echo "Done. The application picks the new permissions up within a few minutes;"
echo "restart the web app if the admin group cannot be set right away."
