#!/usr/bin/env bash # Test all Cloudflare API token permissions # Comprehensive permission testing for API token set -uo pipefail # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[TEST]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } log_result() { if [ "$1" = "0" ]; then log_success "$2" else log_error "$2" fi } # Script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Source .env file if it exists if [ -f "$PROJECT_ROOT/.env" ]; then set +euo pipefail source "$PROJECT_ROOT/.env" 2>/dev/null || true set -euo pipefail fi # Cloudflare API Token CLOUDFLARE_API_TOKEN="${CLOUDFLARE_API_TOKEN:-JSEO_sruWB6lf1id77gtI7HOLVdhkhaR2goPEJIk}" # Zone IDs from .env ZONE_SANKOFA_NEXUS="${CLOUDFLARE_ZONE_ID_SANKOFA_NEXUS:-13e2c26acc5eda15eafa7c8735b00239}" ZONE_D_BIS_ORG="${CLOUDFLARE_ZONE_ID_D_BIS_ORG:-43599eed5d83f1fa641f2aaa276d3c4d}" ZONE_MIM4U_ORG="${CLOUDFLARE_ZONE_ID_MIM4U_ORG:-5dc79e6edf9b9cf353e3cca94f26f454}" ZONE_DEFI_ORACLE_IO="${CLOUDFLARE_ZONE_ID_DEFI_ORACLE_IO:-62c1531bfb1b29d383277f8d16aab13b}" # Function to make API request cf_api_request() { local method="$1" local url="$2" local data="${3:-}" if [ -n "$data" ]; then curl -s -X "$method" "$url" \ -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ -H "Content-Type: application/json" \ --data "$data" else curl -s -X "$method" "$url" \ -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ -H "Content-Type: application/json" fi } # Test counters (initialize to prevent errors) TOTAL_TESTS=${TOTAL_TESTS:-0} PASSED_TESTS=${PASSED_TESTS:-0} FAILED_TESTS=${FAILED_TESTS:-0} # Test function test_permission() { local test_name="$1" local api_call="$2" local expected_success="${3:-true}" TOTAL_TESTS=$((TOTAL_TESTS + 1)) log_info "$test_name" set +e local response=$(eval "$api_call" 2>&1) local api_exit_code=$? set -e # Handle case where response is empty or invalid JSON if [ -z "$response" ]; then log_error " ✗ $test_name (empty response)" FAILED_TESTS=$((FAILED_TESTS + 1)) return 0 # Return 0 to continue script fi if [ $api_exit_code -ne 0 ]; then log_error " ✗ $test_name (API call failed)" log_error " Response: ${response:0:200}" ((FAILED_TESTS++)) return 1 fi local success=$(echo "$response" | jq -r '.success // false' 2>/dev/null || echo "false") local error_code=$(echo "$response" | jq -r '.errors[0].code // empty' 2>/dev/null || echo "") local error_msg=$(echo "$response" | jq -r '.errors[0].message // empty' 2>/dev/null || echo "") if [ "$success" = "true" ] && [ "$expected_success" = "true" ]; then log_success " ✓ $test_name" PASSED_TESTS=$((PASSED_TESTS + 1)) return 0 elif [ "$success" = "false" ] && [ "$expected_success" = "false" ]; then log_success " ✓ $test_name (expected failure)" PASSED_TESTS=$((PASSED_TESTS + 1)) return 0 else log_error " ✗ $test_name" if [ -n "$error_code" ] && [ "$error_code" != "null" ]; then log_error " Error Code: $error_code" fi if [ -n "$error_msg" ] && [ "$error_msg" != "null" ]; then log_error " Error: $error_msg" fi FAILED_TESTS=$((FAILED_TESTS + 1)) return 0 # Return 0 to continue script execution fi } echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🔐 Cloudflare API Token Permission Test" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" log_info "API Token: ${CLOUDFLARE_API_TOKEN:0:20}..." echo "" # Test 1: User Info echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "1. User & Account Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "Get User Info" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/user'" test_permission "List Accounts" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/accounts'" test_permission "List Zones (All)" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones'" set -e echo "" # Test 2: Zone Read Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "2. Zone Read Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "Read sankofa.nexus Zone" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_SANKOFA_NEXUS'" test_permission "Read d-bis.org Zone" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG'" test_permission "Read mim4u.org Zone" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_MIM4U_ORG'" test_permission "Read defi-oracle.io Zone" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_DEFI_ORACLE_IO'" set -e echo "" # Test 3: DNS Record Read Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "3. DNS Record Read Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "List DNS Records (d-bis.org)" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records'" test_permission "Get Specific DNS Record (explorer.d-bis.org)" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records?name=explorer.d-bis.org'" test_permission "List DNS Records (sankofa.nexus)" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_SANKOFA_NEXUS/dns_records'" set -e echo "" # Test 4: DNS Record Write Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "4. DNS Record Write Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Test creating a DNS record TEST_RECORD_DATA=$(jq -n \ --arg name "test-permission-check.d-bis.org" \ --arg content "76.53.10.36" \ '{ type: "A", name: $name, content: $content, proxied: false, ttl: 1 }') set +e test_permission "Create DNS A Record (test)" \ "cf_api_request 'POST' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records' '$TEST_RECORD_DATA'" set -e # Check if test record was created and try to delete it TEST_RECORD_RESPONSE=$(cf_api_request "GET" "https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records?name=test-permission-check.d-bis.org") TEST_RECORD_ID=$(echo "$TEST_RECORD_RESPONSE" | jq -r '.result[0].id // empty' 2>/dev/null || echo "") if [ -n "$TEST_RECORD_ID" ] && [ "$TEST_RECORD_ID" != "null" ]; then set +e test_permission "Delete DNS Record (cleanup)" \ "cf_api_request 'DELETE' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records/$TEST_RECORD_ID'" set -e fi # Test updating an existing record (if we can read them) EXISTING_RECORD=$(cf_api_request "GET" "https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records?per_page=1") EXISTING_RECORD_ID=$(echo "$EXISTING_RECORD" | jq -r '.result[0].id // empty' 2>/dev/null || echo "") if [ -n "$EXISTING_RECORD_ID" ] && [ "$EXISTING_RECORD_ID" != "null" ]; then EXISTING_RECORD_NAME=$(echo "$EXISTING_RECORD" | jq -r '.result[0].name // empty' 2>/dev/null || echo "") EXISTING_RECORD_CONTENT=$(echo "$EXISTING_RECORD" | jq -r '.result[0].content // empty' 2>/dev/null || echo "") UPDATE_RECORD_DATA=$(jq -n \ --arg name "$EXISTING_RECORD_NAME" \ --arg content "$EXISTING_RECORD_CONTENT" \ '{ type: "A", name: $name, content: $content, proxied: false, ttl: 1 }') set +e test_permission "Update DNS Record (existing)" \ "cf_api_request 'PUT' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records/$EXISTING_RECORD_ID' '$UPDATE_RECORD_DATA'" set -e fi echo "" # Test 5: Zone Settings Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "5. Zone Settings Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "Read Zone Settings" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/settings'" test_permission "Read Zone Analytics" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/analytics/dashboard'" set -e echo "" # Test 6: SSL/TLS Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "6. SSL/TLS Certificate Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "List SSL Certificates" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/ssl/certificate_packs'" set -e echo "" # Test 7: Firewall Rules Permissions echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "7. Firewall Rules Permissions" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" set +e test_permission "List Firewall Rules" \ "cf_api_request 'GET' 'https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/firewall/rules'" set -e echo "" # Summary echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "📊 Test Summary" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" log_info "Total Tests: $TOTAL_TESTS" log_success "Passed: $PASSED_TESTS" if [ $FAILED_TESTS -gt 0 ]; then log_error "Failed: $FAILED_TESTS" else log_success "Failed: $FAILED_TESTS" fi echo "" # Permission Analysis echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🔍 Permission Analysis" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # Test DNS write permission specifically DNS_WRITE_TEST=$(cf_api_request "POST" "https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records" "$TEST_RECORD_DATA") DNS_WRITE_SUCCESS=$(echo "$DNS_WRITE_TEST" | jq -r '.success // false' 2>/dev/null || echo "false") DNS_WRITE_ERROR=$(echo "$DNS_WRITE_TEST" | jq -r '.errors[0].message // empty' 2>/dev/null || echo "") if [ "$DNS_WRITE_SUCCESS" = "true" ]; then log_success "✅ DNS Write Permission: GRANTED" # Clean up test record TEST_RECORD_ID=$(echo "$DNS_WRITE_TEST" | jq -r '.result.id // empty' 2>/dev/null || echo "") if [ -n "$TEST_RECORD_ID" ] && [ "$TEST_RECORD_ID" != "null" ]; then cf_api_request "DELETE" "https://api.cloudflare.com/client/v4/zones/$ZONE_D_BIS_ORG/dns_records/$TEST_RECORD_ID" >/dev/null 2>&1 fi else log_error "❌ DNS Write Permission: DENIED" if [ -n "$DNS_WRITE_ERROR" ]; then log_error " Error: $DNS_WRITE_ERROR" fi echo "" log_warn "💡 To fix DNS write permissions:" log_info " 1. Go to: https://dash.cloudflare.com/profile/api-tokens" log_info " 2. Edit your API token" log_info " 3. Add permission: Zone → DNS → Edit" log_info " 4. Include zones: sankofa.nexus, d-bis.org, mim4u.org, defi-oracle.io" fi echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"