#!/bin/bash set -euo pipefail # FUNCTIONS function title() { echo "----------------------------------------" # Center the text local text="$1" local line_length=40 local text_length=${#text} local padding=$(( (line_length - text_length) / 2 )) printf "%*s%s%*s\n" $padding "" "$text" $padding "" echo "----------------------------------------" } function die() { title "error: $1" exit 1 } #------------------------------------------------------------------------------------------------ title "Testing hash_token utility" # Determine if we're running inside or outside the container if [ -f /.dockerenv ] || [ -n "${DOCKER_CONTAINER:-}" ]; then # We're inside the container, run commands directly HASH_TOKEN_CMD="/sos/hash_token --quiet" IN_CONTAINER=true else # We're outside the container, use docker exec HASH_TOKEN_CMD="docker exec sos-test /sos/hash_token --quiet" IN_CONTAINER=false fi # Test 1: Verify hash_token exists echo "1. Checking if hash_token exists..." if [ "$IN_CONTAINER" = true ]; then if [ -f /sos/hash_token ]; then echo "✓ hash_token utility found at /sos/hash_token" else die "hash_token utility not found at /sos/hash_token" fi else if docker exec sos-test ls /sos/hash_token >/dev/null 2>&1; then echo "✓ hash_token utility found in container" else die "hash_token utility not found in container at /sos/hash_token" fi fi # Test 2: Generate a hash and verify format echo "2. Testing hash generation..." TEST_TOKEN="test-token-$(date +%s)" HASH=$($HASH_TOKEN_CMD "$TEST_TOKEN" 2>/dev/null) if [ -z "$HASH" ]; then die "hash_token did not produce any output" fi echo "Generated hash: $HASH" # Verify hash format (should start with $2b$ for bcrypt) if [[ $HASH == \$2b\$* ]]; then echo "✓ Hash has correct bcrypt format" else die "Hash does not have correct bcrypt format (should start with \$2b\$)" fi # Test 3: Verify hash length (bcrypt hashes are typically 60 characters) HASH_LENGTH=${#HASH} if [ $HASH_LENGTH -ge 59 ] && [ $HASH_LENGTH -le 60 ]; then echo "✓ Hash has correct length ($HASH_LENGTH characters)" else die "Hash has incorrect length ($HASH_LENGTH characters, expected ~60)" fi # Test 4: Generate multiple hashes for same token and verify they're different echo "3. Testing hash uniqueness (same token should produce different hashes)..." HASH1=$($HASH_TOKEN_CMD "same-token" 2>/dev/null) HASH2=$($HASH_TOKEN_CMD "same-token" 2>/dev/null) if [ "$HASH1" != "$HASH2" ]; then echo "✓ Same token produces different hashes (expected bcrypt behavior)" else echo "Warning: Same token produced identical hashes (unexpected but not critical)" fi # Test 5: Test with special characters echo "4. Testing with special characters..." SPECIAL_TOKEN='test!@#$%^&*()_+-=[]{}|;:,.<>?' SPECIAL_HASH=$($HASH_TOKEN_CMD "$SPECIAL_TOKEN" 2>/dev/null || echo "FAILED") if [ "$SPECIAL_HASH" != "FAILED" ] && [[ $SPECIAL_HASH == \$2b\$* ]]; then echo "✓ Special characters handled correctly" else die "Failed to handle special characters in token" fi # Test 6: Test with empty token (should fail or produce output) echo "5. Testing with empty token..." EMPTY_RESULT=$($HASH_TOKEN_CMD "" 2>&1 || echo "EXPECTED_FAILURE") if [ "$EMPTY_RESULT" == "EXPECTED_FAILURE" ] || [ -z "$EMPTY_RESULT" ]; then echo "✓ Empty token handled appropriately" else # Empty token might still produce a hash, which is also acceptable if [[ $EMPTY_RESULT == \$2b\$* ]]; then echo "✓ Empty token produces valid hash" else echo "Warning: Unexpected behavior with empty token" fi fi # Test 7: Test authentication with generated hash echo "6. Testing authentication with generated hash..." # Generate a new token and hash AUTH_TOKEN="auth-test-$(date +%s)" # Use the base command without --quiet for this specific case if [ "$IN_CONTAINER" = true ]; then AUTH_HASH=$(/sos/hash_token --quiet "$AUTH_TOKEN" 2>/dev/null) else AUTH_HASH=$(docker exec sos-test /sos/hash_token --quiet "$AUTH_TOKEN" 2>/dev/null) fi # Create a temporary config with the new hash TEMP_CONFIG="/tmp/test_hash_config.json" cat > "$TEMP_CONFIG" << EOF { "write_tokens": ["$AUTH_HASH"], "rate_limiting": { "auth_rate_limit": 5, "auth_window_seconds": 2 }, "logging": { "log_file_path": "/data/test.log", "log_level": "info" }, "storage_path": "/data/storage", "port": 7704, "host": "127.0.0.1" } EOF if [ "$IN_CONTAINER" = true ]; then # We're inside the container, start server directly /sos/sos "$TEMP_CONFIG" & SERVER_PID=$! # Wait for the new instance to start sleep 2 # Test authentication with the token echo "Testing upload with generated token..." echo "test content" > /tmp/test_upload.txt UPLOAD_RESPONSE=$(curl -s -X PUT \ -H "Authorization: Bearer $AUTH_TOKEN" \ -F "file=@/tmp/test_upload.txt" \ -F 'metadata={"labeltags":["hashtest:latest"]}' \ "http://127.0.0.1:7704/upload" 2>/dev/null || echo "FAILED") if [ "$UPLOAD_RESPONSE" != "FAILED" ] && echo "$UPLOAD_RESPONSE" | grep -q "hash"; then echo "✓ Authentication successful with generated hash" # Extract hash and clean up OBJECT_HASH=$(echo "$UPLOAD_RESPONSE" | grep -oP '"hash"\s*:\s*"\K[^"]+' || true) if [ -n "$OBJECT_HASH" ]; then curl -s -H "Authorization: Bearer $AUTH_TOKEN" \ "http://127.0.0.1:7704/deleteobject?hash=$OBJECT_HASH" >/dev/null 2>&1 || true fi else echo "Warning: Could not test authentication (secondary server may not have started)" fi # Kill the test server instance kill $SERVER_PID 2>/dev/null || true else # We're outside the container, use docker exec docker cp "$TEMP_CONFIG" sos-test:/tmp/test_hash_config.json docker exec -d sos-test /sos/sos /tmp/test_hash_config.json # Wait for the new instance to start sleep 2 # Test authentication with the token echo "Testing upload with generated token..." echo "test content" > /tmp/test_upload.txt docker cp /tmp/test_upload.txt sos-test:/tmp/test_upload.txt UPLOAD_RESPONSE=$(docker exec sos-test curl -s -X PUT \ -H "Authorization: Bearer $AUTH_TOKEN" \ -F "file=@/tmp/test_upload.txt" \ -F 'metadata={"labeltags":["hashtest:latest"]}' \ "http://127.0.0.1:7704/upload" 2>/dev/null || echo "FAILED") if [ "$UPLOAD_RESPONSE" != "FAILED" ] && echo "$UPLOAD_RESPONSE" | grep -q "hash"; then echo "✓ Authentication successful with generated hash" # Extract hash and clean up OBJECT_HASH=$(echo "$UPLOAD_RESPONSE" | grep -oP '"hash"\s*:\s*"\K[^"]+' || true) if [ -n "$OBJECT_HASH" ]; then docker exec sos-test curl -s -H "Authorization: Bearer $AUTH_TOKEN" \ "http://127.0.0.1:7704/deleteobject?hash=$OBJECT_HASH" >/dev/null 2>&1 || true fi else echo "Warning: Could not test authentication (secondary server may not have started)" fi # Kill the test server instance docker exec sos-test pkill -f "sos.*7704" 2>/dev/null || true fi # Cleanup rm -f "$TEMP_CONFIG" /tmp/test_upload.txt title "hash_token tests completed"