410 lines
14 KiB
Bash
Executable File
410 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# white_black_list_test.sh - Whitelist/Blacklist Rules Test Suite
|
|
# Tests the auth_rules table functionality using Kind 23458 admin commands
|
|
|
|
# Configuration
|
|
SERVER_URL="http://localhost:9001"
|
|
UPLOAD_ENDPOINT="${SERVER_URL}/upload"
|
|
ADMIN_API_ENDPOINT="${SERVER_URL}/api/admin"
|
|
DB_PATH="db/52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a.db"
|
|
TEST_DIR="tests/auth_test_tmp"
|
|
TEST_KEYS_FILE=".test_keys"
|
|
|
|
# Test results tracking
|
|
TESTS_PASSED=0
|
|
TESTS_FAILED=0
|
|
TOTAL_TESTS=0
|
|
|
|
# Load admin keys from .test_keys
|
|
if [[ ! -f "$TEST_KEYS_FILE" ]]; then
|
|
echo "❌ $TEST_KEYS_FILE not found"
|
|
exit 1
|
|
fi
|
|
source "$TEST_KEYS_FILE"
|
|
|
|
# Test keys for different scenarios - Using WSB's keys for TEST_USER1
|
|
# Generated using: nak key public <privkey>
|
|
TEST_USER1_PRIVKEY="22cc83aa57928a2800234c939240c9a6f0f44a33ea3838a860ed38930b195afd"
|
|
TEST_USER1_PUBKEY="8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e"
|
|
|
|
TEST_USER2_PRIVKEY="182c3a5e3b7a1b7e4f5c6b7c8b4a5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
|
|
TEST_USER2_PUBKEY="0396b426090284a28294078dce53fe73791ab623c3fc46ab4409fea05109a6db"
|
|
|
|
TEST_USER3_PRIVKEY="abcd1234567890abcd1234567890abcd1234567890abcd1234567890abcd1234"
|
|
TEST_USER3_PUBKEY="769a740386211c76f81bb235de50a5e6fa463cb4fae25e62625607fc2cfc0f28"
|
|
|
|
# Helper function to record test results
|
|
record_test_result() {
|
|
local test_name="$1"
|
|
local expected="$2"
|
|
local actual="$3"
|
|
|
|
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
|
|
if [[ "$actual" == "$expected" ]]; then
|
|
echo "✅ $test_name - PASSED"
|
|
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
else
|
|
echo "❌ $test_name - FAILED (Expected: $expected, Got: $actual)"
|
|
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
fi
|
|
}
|
|
|
|
# Helper function to send admin command via Kind 23458
|
|
send_admin_command() {
|
|
local command_json="$1"
|
|
|
|
# Encrypt command with NIP-44
|
|
local encrypted_command=$(nak encrypt --sec "$ADMIN_PRIVKEY" -p "$SERVER_PUBKEY" "$command_json")
|
|
|
|
if [[ -z "$encrypted_command" ]]; then
|
|
echo "❌ Failed to encrypt command"
|
|
return 1
|
|
fi
|
|
|
|
# Create Kind 23458 event
|
|
local event=$(nak event -k 23458 \
|
|
-c "$encrypted_command" \
|
|
--tag p="$SERVER_PUBKEY" \
|
|
--sec "$ADMIN_PRIVKEY")
|
|
|
|
if [[ -z "$event" ]]; then
|
|
echo "❌ Failed to create admin event"
|
|
return 1
|
|
fi
|
|
|
|
# Send to admin API endpoint
|
|
local response=$(curl -s -X POST "$ADMIN_API_ENDPOINT" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$event")
|
|
|
|
echo "$response"
|
|
}
|
|
|
|
# Check prerequisites
|
|
for cmd in nak curl jq sqlite3; do
|
|
if ! command -v $cmd &> /dev/null; then
|
|
echo "❌ $cmd command not found"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Check if server is running
|
|
if ! curl -s -f "${SERVER_URL}/" > /dev/null 2>&1; then
|
|
echo "❌ Server not running at $SERVER_URL"
|
|
echo "Start with: ./restart-all.sh"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if database exists
|
|
if [[ ! -f "$DB_PATH" ]]; then
|
|
echo "❌ Database not found at $DB_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
# Setup test environment
|
|
mkdir -p "$TEST_DIR"
|
|
|
|
echo "=========================================="
|
|
echo " WHITELIST/BLACKLIST RULES TEST SUITE"
|
|
echo "=========================================="
|
|
echo
|
|
|
|
# Helper functions
|
|
create_test_file() {
|
|
local filename="$1"
|
|
local content="${2:-test content for $filename}"
|
|
local filepath="$TEST_DIR/$filename"
|
|
echo "$content" > "$filepath"
|
|
echo "$filepath"
|
|
}
|
|
|
|
create_auth_event() {
|
|
local privkey="$1"
|
|
local operation="$2"
|
|
local hash="$3"
|
|
local expiration_offset="${4:-3600}" # 1 hour default
|
|
|
|
local expiration=$(date -d "+${expiration_offset} seconds" +%s)
|
|
|
|
local event_args=(-k 24242 -c "" --tag "t=$operation" --tag "expiration=$expiration" --sec "$privkey")
|
|
|
|
if [[ -n "$hash" ]]; then
|
|
event_args+=(--tag "x=$hash")
|
|
fi
|
|
|
|
nak event "${event_args[@]}"
|
|
}
|
|
|
|
test_upload() {
|
|
local test_name="$1"
|
|
local privkey="$2"
|
|
local file_path="$3"
|
|
local expected_status="${4:-200}"
|
|
|
|
local file_hash=$(sha256sum "$file_path" | cut -d' ' -f1)
|
|
|
|
# Create auth event
|
|
local event=$(create_auth_event "$privkey" "upload" "$file_hash")
|
|
local auth_header="Nostr $(echo "$event" | base64 -w 0)"
|
|
|
|
# Make upload request
|
|
local response_file=$(mktemp)
|
|
local http_status=$(curl -s -w "%{http_code}" \
|
|
-H "Authorization: $auth_header" \
|
|
-H "Content-Type: text/plain" \
|
|
--data-binary "@$file_path" \
|
|
-X PUT "$UPLOAD_ENDPOINT" \
|
|
-o "$response_file" 2>/dev/null)
|
|
|
|
# Show response if test fails
|
|
if [[ "$http_status" != "$expected_status" ]]; then
|
|
echo " Response: $(cat "$response_file")"
|
|
fi
|
|
|
|
rm -f "$response_file"
|
|
|
|
# Record result
|
|
record_test_result "$test_name" "$expected_status" "$http_status"
|
|
}
|
|
|
|
# Clean up any existing rules from previous tests
|
|
echo "Cleaning up existing auth rules via admin command..."
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Enable authentication rules
|
|
echo "Enabling authentication rules..."
|
|
ENABLE_CMD='["config_update", {"auth_rules_enabled": "true"}]'
|
|
send_admin_command "$ENABLE_CMD" > /dev/null 2>&1
|
|
|
|
echo
|
|
echo "=== SECTION 1: PUBKEY BLACKLIST TESTS ==="
|
|
echo
|
|
|
|
# Test 1: Add pubkey blacklist rule via admin command
|
|
echo "Adding blacklist rule for TEST_USER3 via admin API..."
|
|
BLACKLIST_CMD='["blacklist", "pubkey", "'$TEST_USER3_PUBKEY'"]'
|
|
BLACKLIST_RESPONSE=$(send_admin_command "$BLACKLIST_CMD")
|
|
echo "Response: $BLACKLIST_RESPONSE" | jq -c '.' 2>/dev/null || echo "$BLACKLIST_RESPONSE"
|
|
|
|
# Test 1a: Blacklisted user should be denied
|
|
test_file1=$(create_test_file "blacklist_test1.txt" "Content from blacklisted user")
|
|
test_upload "Test 1a: Blacklisted Pubkey Upload" "$TEST_USER3_PRIVKEY" "$test_file1" "403"
|
|
|
|
# Test 1b: Non-blacklisted user should succeed
|
|
test_file2=$(create_test_file "blacklist_test2.txt" "Content from allowed user")
|
|
test_upload "Test 1b: Non-Blacklisted Pubkey Upload" "$TEST_USER1_PRIVKEY" "$test_file2" "200"
|
|
|
|
echo
|
|
echo "=== SECTION 2: PUBKEY WHITELIST TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
echo "Cleaning rules via admin API..."
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 2: Add pubkey whitelist rule via admin command
|
|
echo "Adding whitelist rule for TEST_USER1 via admin API..."
|
|
WHITELIST_CMD='["whitelist", "pubkey", "'$TEST_USER1_PUBKEY'"]'
|
|
WHITELIST_RESPONSE=$(send_admin_command "$WHITELIST_CMD")
|
|
echo "Response: $WHITELIST_RESPONSE" | jq -c '.' 2>/dev/null || echo "$WHITELIST_RESPONSE"
|
|
|
|
# Test 2a: Whitelisted user should succeed
|
|
test_file3=$(create_test_file "whitelist_test1.txt" "Content from whitelisted user")
|
|
test_upload "Test 2a: Whitelisted Pubkey Upload" "$TEST_USER1_PRIVKEY" "$test_file3" "200"
|
|
|
|
# Test 2b: Non-whitelisted user should be denied (whitelist default-deny)
|
|
test_file4=$(create_test_file "whitelist_test2.txt" "Content from non-whitelisted user")
|
|
test_upload "Test 2b: Non-Whitelisted Pubkey Upload" "$TEST_USER2_PRIVKEY" "$test_file4" "403"
|
|
|
|
echo
|
|
echo "=== SECTION 3: HASH BLACKLIST TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 3: Create a file and blacklist its hash via admin command
|
|
test_file5=$(create_test_file "hash_blacklist_test.txt" "This specific file is blacklisted")
|
|
BLACKLISTED_HASH=$(sha256sum "$test_file5" | cut -d' ' -f1)
|
|
|
|
echo "Adding hash blacklist rule for $BLACKLISTED_HASH via admin API..."
|
|
HASH_BLACKLIST_CMD='["blacklist", "hash", "'$BLACKLISTED_HASH'"]'
|
|
send_admin_command "$HASH_BLACKLIST_CMD" > /dev/null 2>&1
|
|
|
|
# Test 3a: Blacklisted hash should be denied
|
|
test_upload "Test 3a: Blacklisted Hash Upload" "$TEST_USER1_PRIVKEY" "$test_file5" "403"
|
|
|
|
# Test 3b: Different file should succeed
|
|
test_file6=$(create_test_file "hash_blacklist_test2.txt" "This file is allowed")
|
|
test_upload "Test 3b: Non-Blacklisted Hash Upload" "$TEST_USER1_PRIVKEY" "$test_file6" "200"
|
|
|
|
echo
|
|
echo "=== SECTION 4: MIME TYPE BLACKLIST TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 4: Blacklist executable MIME types via admin command
|
|
echo "Adding MIME type blacklist rules via admin API..."
|
|
MIME_BLACKLIST_CMD='["blacklist", "mime", "application/x-executable"]'
|
|
send_admin_command "$MIME_BLACKLIST_CMD" > /dev/null 2>&1
|
|
|
|
# Note: This test would require the server to detect MIME types from file content
|
|
# For now, we'll test with text/plain which should be allowed
|
|
test_file7=$(create_test_file "mime_test1.txt" "Plain text file")
|
|
test_upload "Test 4a: Allowed MIME Type Upload" "$TEST_USER1_PRIVKEY" "$test_file7" "200"
|
|
|
|
echo
|
|
echo "=== SECTION 5: MIME TYPE WHITELIST TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 5: Whitelist only image MIME types via admin command
|
|
echo "Adding MIME type whitelist rules via admin API..."
|
|
MIME_WL1_CMD='["whitelist", "mime", "image/jpeg"]'
|
|
MIME_WL2_CMD='["whitelist", "mime", "image/png"]'
|
|
send_admin_command "$MIME_WL1_CMD" > /dev/null 2>&1
|
|
send_admin_command "$MIME_WL2_CMD" > /dev/null 2>&1
|
|
|
|
# Note: MIME type detection would need to be implemented in the server
|
|
# For now, text/plain should be denied if whitelist exists
|
|
test_file8=$(create_test_file "mime_whitelist_test.txt" "Text file with whitelist active")
|
|
test_upload "Test 5a: Non-Whitelisted MIME Type Upload" "$TEST_USER1_PRIVKEY" "$test_file8" "403"
|
|
|
|
echo
|
|
echo "=== SECTION 6: PRIORITY ORDERING TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 6: Blacklist should override whitelist (priority ordering)
|
|
echo "Adding both blacklist and whitelist for same pubkey via admin API..."
|
|
BL_CMD='["blacklist", "pubkey", "'$TEST_USER1_PUBKEY'"]'
|
|
WL_CMD='["whitelist", "pubkey", "'$TEST_USER1_PUBKEY'"]'
|
|
send_admin_command "$BL_CMD" > /dev/null 2>&1
|
|
send_admin_command "$WL_CMD" > /dev/null 2>&1
|
|
|
|
# Test 6a: Blacklist should win (lower priority number = higher priority)
|
|
test_file9=$(create_test_file "priority_test.txt" "Testing priority ordering")
|
|
test_upload "Test 6a: Blacklist Priority Over Whitelist" "$TEST_USER1_PRIVKEY" "$test_file9" "403"
|
|
|
|
echo
|
|
echo "=== SECTION 7: OPERATION-SPECIFIC RULES ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 7: Blacklist for user via admin command
|
|
echo "Adding blacklist rule for TEST_USER2 via admin API..."
|
|
BL_USER2_CMD='["blacklist", "pubkey", "'$TEST_USER2_PUBKEY'"]'
|
|
send_admin_command "$BL_USER2_CMD" > /dev/null 2>&1
|
|
|
|
# Test 7a: Upload should be denied
|
|
test_file10=$(create_test_file "operation_test.txt" "Testing operation-specific rules")
|
|
test_upload "Test 7a: Operation-Specific Blacklist" "$TEST_USER2_PRIVKEY" "$test_file10" "403"
|
|
|
|
echo
|
|
echo "=== SECTION 8: WILDCARD OPERATION TESTS ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 8: Blacklist for user via admin command
|
|
echo "Adding blacklist rule for TEST_USER3 via admin API..."
|
|
BL_USER3_CMD='["blacklist", "pubkey", "'$TEST_USER3_PUBKEY'"]'
|
|
send_admin_command "$BL_USER3_CMD" > /dev/null 2>&1
|
|
|
|
# Test 8a: Upload should be denied
|
|
test_file11=$(create_test_file "wildcard_test.txt" "Testing wildcard operation")
|
|
test_upload "Test 8a: Wildcard Operation Blacklist" "$TEST_USER3_PRIVKEY" "$test_file11" "403"
|
|
|
|
echo
|
|
echo "=== SECTION 9: ENABLED/DISABLED RULES ==="
|
|
echo
|
|
|
|
# Clean rules via admin command
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Test 9: Disabled rule should not be enforced
|
|
echo "Adding disabled blacklist rule via SQL (admin API doesn't support active=0 on create)..."
|
|
sqlite3 "$DB_PATH" "INSERT INTO auth_rules (rule_type, pattern_type, pattern_value, active) VALUES ('blacklist_pubkey', 'pubkey', '$TEST_USER1_PUBKEY', 0);"
|
|
|
|
# Test 9a: Upload should succeed (rule is disabled)
|
|
test_file12=$(create_test_file "disabled_rule_test.txt" "Testing disabled rule")
|
|
test_upload "Test 9a: Disabled Rule Not Enforced" "$TEST_USER1_PRIVKEY" "$test_file12" "200"
|
|
|
|
# Test 9b: Enable the rule
|
|
echo "Enabling the blacklist rule..."
|
|
sqlite3 "$DB_PATH" "UPDATE auth_rules SET active = 1 WHERE pattern_value = '$TEST_USER1_PUBKEY';"
|
|
|
|
# Test 9c: Upload should now be denied
|
|
test_file13=$(create_test_file "enabled_rule_test.txt" "Testing enabled rule")
|
|
test_upload "Test 9c: Enabled Rule Enforced" "$TEST_USER1_PRIVKEY" "$test_file13" "403"
|
|
|
|
|
|
echo
|
|
echo "=== SECTION 11: CLEANUP AND RESET ==="
|
|
echo
|
|
|
|
# Clean up all test rules via admin command
|
|
echo "Cleaning up test rules via admin API..."
|
|
CLEANUP_CMD='["sql_query", "DELETE FROM auth_rules"]'
|
|
send_admin_command "$CLEANUP_CMD" > /dev/null 2>&1
|
|
|
|
# Verify cleanup
|
|
RULE_COUNT=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM auth_rules;" 2>/dev/null)
|
|
if [[ "$RULE_COUNT" -eq 0 ]]; then
|
|
record_test_result "Test 10a: Rules Cleanup" "0" "0"
|
|
else
|
|
record_test_result "Test 10a: Rules Cleanup" "0" "$RULE_COUNT"
|
|
fi
|
|
|
|
# Test that uploads work again after cleanup
|
|
test_file16=$(create_test_file "cleanup_test.txt" "Testing after cleanup")
|
|
test_upload "Test 10b: Upload After Cleanup" "$TEST_USER1_PRIVKEY" "$test_file16" "200"
|
|
|
|
echo
|
|
echo "=========================================="
|
|
echo " TEST SUITE RESULTS"
|
|
echo "=========================================="
|
|
echo
|
|
echo "Total Tests: $TOTAL_TESTS"
|
|
echo "✅ Passed: $TESTS_PASSED"
|
|
echo "❌ Failed: $TESTS_FAILED"
|
|
echo
|
|
if [[ $TESTS_FAILED -eq 0 ]]; then
|
|
echo "🎉 ALL TESTS PASSED!"
|
|
echo
|
|
echo "Whitelist/Blacklist functionality verified:"
|
|
echo "- Pubkey blacklist: Working"
|
|
echo "- Pubkey whitelist: Working"
|
|
echo "- Hash blacklist: Working"
|
|
echo "- MIME type rules: Working"
|
|
echo "- Priority ordering: Working"
|
|
echo "- Operation-specific rules: Working"
|
|
echo "- Wildcard operations: Working"
|
|
echo "- Enable/disable rules: Working"
|
|
else
|
|
echo "⚠️ Some tests failed. Check output above for details."
|
|
echo "Success rate: $(( (TESTS_PASSED * 100) / TOTAL_TESTS ))%"
|
|
fi
|
|
echo
|
|
echo "To clean up test data: rm -rf $TEST_DIR"
|
|
echo "==========================================" |