Move smoke-test.sh to tests/, make it local-only
- Move from rpi/ to tests/ directory - Add to .gitignore (local tool, not part of distribution) - Pytest unit tests remain tracked 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -71,6 +71,9 @@ scripts/
|
|||||||
frontends/web/instance/
|
frontends/web/instance/
|
||||||
frontends/web/certs/
|
frontends/web/certs/
|
||||||
|
|
||||||
|
# Integration/smoke tests (local tools)
|
||||||
|
tests/smoke-test.sh
|
||||||
|
|
||||||
# RPi image build artifacts
|
# RPi image build artifacts
|
||||||
*.img
|
*.img
|
||||||
*.img.xz
|
*.img.xz
|
||||||
|
|||||||
@@ -1,573 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Stegasoo Pi Image Smoke Test
|
|
||||||
# Automated testing of a fresh Pi image
|
|
||||||
#
|
|
||||||
# Usage: ./smoke-test.sh [ip] [--https] [--443] [--port=PORT] [--docker]
|
|
||||||
# Default IP: 192.168.0.4 (or localhost for --docker)
|
|
||||||
# --https Use HTTPS (port 5000)
|
|
||||||
# --443 Use HTTPS on port 443
|
|
||||||
# --port=N Specify custom port
|
|
||||||
# --docker Docker mode: skip systemd/SSH checks, use localhost
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
CYAN='\033[0;36m'
|
|
||||||
BOLD='\033[1m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
PI_IP="192.168.0.4"
|
|
||||||
HTTPS=false
|
|
||||||
PORT=5000
|
|
||||||
DOCKER_MODE=false
|
|
||||||
|
|
||||||
# Parse arguments
|
|
||||||
for arg in "$@"; do
|
|
||||||
case $arg in
|
|
||||||
--https) HTTPS=true ;;
|
|
||||||
--443) HTTPS=true; PORT=443 ;;
|
|
||||||
--port=*) PORT="${arg#*=}" ;;
|
|
||||||
--docker) DOCKER_MODE=true; PI_IP="localhost" ;;
|
|
||||||
--*) ;; # Ignore other flags
|
|
||||||
*)
|
|
||||||
# If it looks like an IP, use it
|
|
||||||
if [[ "$arg" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
PI_IP="$arg"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$HTTPS" = true ]; then
|
|
||||||
if [ "$PORT" = "443" ]; then
|
|
||||||
BASE_URL="https://$PI_IP"
|
|
||||||
else
|
|
||||||
BASE_URL="https://$PI_IP:$PORT"
|
|
||||||
fi
|
|
||||||
CURL_OPTS="-k" # Allow self-signed certs
|
|
||||||
else
|
|
||||||
BASE_URL="http://$PI_IP:$PORT"
|
|
||||||
CURL_OPTS=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test credentials
|
|
||||||
ADMIN_USER="admin"
|
|
||||||
ADMIN_PASS="stegasoo"
|
|
||||||
REGULAR_USER="smokeuser"
|
|
||||||
REGULAR_PASS="SmokeUser123!"
|
|
||||||
|
|
||||||
# Temp files
|
|
||||||
COOKIE_JAR=$(mktemp)
|
|
||||||
COOKIE_JAR_USER=$(mktemp)
|
|
||||||
TEST_IMAGE=$(mktemp --suffix=.png)
|
|
||||||
ENCODED_IMAGE=$(mktemp --suffix=.png)
|
|
||||||
RESPONSE=$(mktemp)
|
|
||||||
|
|
||||||
ENCODED_IMAGE_USER=$(mktemp --suffix=.png)
|
|
||||||
QR_IMAGE=$(mktemp --suffix=.png)
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
rm -f "$COOKIE_JAR" "$COOKIE_JAR_USER" "$TEST_IMAGE" "$ENCODED_IMAGE" "$ENCODED_IMAGE_USER" "$QR_IMAGE" "$RESPONSE"
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Create a simple test image (red square)
|
|
||||||
create_test_image() {
|
|
||||||
if command -v convert &>/dev/null; then
|
|
||||||
convert -size 100x100 xc:red "$TEST_IMAGE"
|
|
||||||
elif command -v python3 &>/dev/null; then
|
|
||||||
python3 -c "
|
|
||||||
from PIL import Image
|
|
||||||
img = Image.new('RGB', (100, 100), color='red')
|
|
||||||
img.save('$TEST_IMAGE')
|
|
||||||
"
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}Warning: No image tool available, skipping encode/decode tests${NC}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Results tracking
|
|
||||||
TESTS_PASSED=0
|
|
||||||
TESTS_FAILED=0
|
|
||||||
|
|
||||||
pass() {
|
|
||||||
echo -e " ${GREEN}[PASS]${NC} $1"
|
|
||||||
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
fail() {
|
|
||||||
echo -e " ${RED}[FAIL]${NC} $1"
|
|
||||||
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
skip() {
|
|
||||||
echo -e " ${YELLOW}[SKIP]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Header
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
|
||||||
if [ "$DOCKER_MODE" = true ]; then
|
|
||||||
echo -e "${CYAN}║ Stegasoo Docker Smoke Test ║${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${CYAN}║ Stegasoo Pi Image Smoke Test ║${NC}"
|
|
||||||
fi
|
|
||||||
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
|
||||||
echo ""
|
|
||||||
echo -e "Target: ${YELLOW}$BASE_URL${NC}"
|
|
||||||
if [ "$DOCKER_MODE" = true ]; then
|
|
||||||
echo -e "Mode: ${YELLOW}Docker${NC}"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 1: Web UI Reachable
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo -e "${BOLD}[1/9] Web UI Accessibility${NC}"
|
|
||||||
|
|
||||||
if curl $CURL_OPTS -s -o /dev/null -w "%{http_code}" "$BASE_URL" | grep -q "200\|302"; then
|
|
||||||
pass "Web UI is reachable"
|
|
||||||
else
|
|
||||||
fail "Web UI not reachable at $BASE_URL"
|
|
||||||
echo -e "${RED}Cannot continue without web access. Is the Pi running?${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if /login redirects to setup (meaning no users exist)
|
|
||||||
LOGIN_REDIRECT=$(curl $CURL_OPTS -s -o /dev/null -w "%{redirect_url}" "$BASE_URL/login")
|
|
||||||
if echo "$LOGIN_REDIRECT" | grep -q "setup"; then
|
|
||||||
pass "Login redirects to setup (no users yet)"
|
|
||||||
NEEDS_SETUP=true
|
|
||||||
else
|
|
||||||
# Check if we can access login page directly
|
|
||||||
if curl $CURL_OPTS -s "$BASE_URL/login" | grep -qi "login\|password"; then
|
|
||||||
pass "Login page accessible (users exist)"
|
|
||||||
NEEDS_SETUP=false
|
|
||||||
else
|
|
||||||
# Fallback: check homepage content
|
|
||||||
if curl $CURL_OPTS -s "$BASE_URL" | grep -q "setup\|Setup\|Create.*Admin"; then
|
|
||||||
pass "Setup page detected"
|
|
||||||
NEEDS_SETUP=true
|
|
||||||
else
|
|
||||||
pass "Assuming configured (login available)"
|
|
||||||
NEEDS_SETUP=false
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 2: Create Admin User (if needed)
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[2/9] Admin Setup${NC}"
|
|
||||||
|
|
||||||
if [ "$NEEDS_SETUP" = true ]; then
|
|
||||||
# Get CSRF token from setup page
|
|
||||||
SETUP_PAGE=$(curl $CURL_OPTS -s -c "$COOKIE_JAR" "$BASE_URL/setup")
|
|
||||||
CSRF_TOKEN=$(echo "$SETUP_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
if [ -z "$CSRF_TOKEN" ]; then
|
|
||||||
# Try alternate pattern
|
|
||||||
CSRF_TOKEN=$(echo "$SETUP_PAGE" | grep -oP 'csrf_token.*?value="\K[^"]+' || echo "")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create admin user
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$RESPONSE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/setup" \
|
|
||||||
-d "username=$ADMIN_USER" \
|
|
||||||
-d "password=$ADMIN_PASS" \
|
|
||||||
-d "password_confirm=$ADMIN_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "200" ]; then
|
|
||||||
if curl $CURL_OPTS -s "$BASE_URL" | grep -q "login\|Login"; then
|
|
||||||
pass "Admin user created successfully"
|
|
||||||
else
|
|
||||||
pass "Setup completed (assuming success)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
fail "Failed to create admin user (HTTP $HTTP_CODE)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Setup already complete"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 3: Admin Login
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[3/9] Admin Authentication${NC}"
|
|
||||||
|
|
||||||
# Get login page and CSRF
|
|
||||||
LOGIN_PAGE=$(curl $CURL_OPTS -s -c "$COOKIE_JAR" "$BASE_URL/login")
|
|
||||||
CSRF_TOKEN=$(echo "$LOGIN_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
# Try login as admin
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$RESPONSE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/login" \
|
|
||||||
-d "username=$ADMIN_USER" \
|
|
||||||
-d "password=$ADMIN_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN" \
|
|
||||||
-L)
|
|
||||||
|
|
||||||
# Check if we're logged in by looking for logout link (not encode/decode, those are public)
|
|
||||||
HOMEPAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" -c "$COOKIE_JAR" "$BASE_URL/")
|
|
||||||
if echo "$HOMEPAGE" | grep -qi "logout"; then
|
|
||||||
pass "Admin login successful"
|
|
||||||
ADMIN_LOGGED_IN=true
|
|
||||||
elif echo "$HOMEPAGE" | grep -qi "login"; then
|
|
||||||
fail "Admin login failed (still showing login link)"
|
|
||||||
ADMIN_LOGGED_IN=false
|
|
||||||
else
|
|
||||||
# No login or logout link - might be unauthenticated site
|
|
||||||
pass "Admin login successful (no auth required)"
|
|
||||||
ADMIN_LOGGED_IN=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 4: Admin Encode/Decode
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[4/9] Admin Encode/Decode${NC}"
|
|
||||||
|
|
||||||
if [ "$ADMIN_LOGGED_IN" = true ]; then
|
|
||||||
ENCODE_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/encode")
|
|
||||||
|
|
||||||
if echo "$ENCODE_PAGE" | grep -qi "encode\|message\|image\|upload"; then
|
|
||||||
pass "Encode page loads"
|
|
||||||
else
|
|
||||||
fail "Encode page not accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try actual encoding if we have image tools
|
|
||||||
if create_test_image 2>/dev/null; then
|
|
||||||
CSRF_TOKEN=$(echo "$ENCODE_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
# For encode: use same image as reference_photo and carrier (for simplicity)
|
|
||||||
# First POST (no redirect follow), get Location header, then GET result page
|
|
||||||
ENCODE_RESULT=$(curl $CURL_OPTS -s -D - -o /dev/null \
|
|
||||||
-b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/encode" \
|
|
||||||
-F "reference_photo=@$TEST_IMAGE" \
|
|
||||||
-F "carrier=@$TEST_IMAGE" \
|
|
||||||
-F "message=Admin smoke test" \
|
|
||||||
-F "passphrase=smoke test phrase" \
|
|
||||||
-F "pin=123456" \
|
|
||||||
-F "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
# Extract redirect location
|
|
||||||
RESULT_LOCATION=$(echo "$ENCODE_RESULT" | grep -i "^location:" | tr -d '\r' | awk '{print $2}')
|
|
||||||
|
|
||||||
if [ -n "$RESULT_LOCATION" ]; then
|
|
||||||
# GET the result page
|
|
||||||
RESULT_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL$RESULT_LOCATION")
|
|
||||||
|
|
||||||
# Look for download link in result page
|
|
||||||
DOWNLOAD_URL=$(echo "$RESULT_PAGE" | grep -oP 'href="(/encode/download/[^"]+)"' | head -1 | grep -oP '/encode/download/[^"]+')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$DOWNLOAD_URL" ]; then
|
|
||||||
# Download the encoded image
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$ENCODED_IMAGE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR" "$BASE_URL$DOWNLOAD_URL")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "200" ] && file "$ENCODED_IMAGE" | grep -qi "image\|PNG\|JPEG"; then
|
|
||||||
pass "Admin encoding works"
|
|
||||||
|
|
||||||
# Now decode it
|
|
||||||
DECODE_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/decode")
|
|
||||||
CSRF_TOKEN=$(echo "$DECODE_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
DECODED=$(curl $CURL_OPTS -s \
|
|
||||||
-b "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/decode" \
|
|
||||||
-F "reference_photo=@$TEST_IMAGE" \
|
|
||||||
-F "stego_image=@$ENCODED_IMAGE" \
|
|
||||||
-F "passphrase=smoke test phrase" \
|
|
||||||
-F "pin=123456" \
|
|
||||||
-F "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
if echo "$DECODED" | grep -q "Admin smoke test"; then
|
|
||||||
pass "Admin decoding works"
|
|
||||||
else
|
|
||||||
fail "Admin decode failed"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
fail "Failed to download encoded image (HTTP $HTTP_CODE)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Check for error messages in result page
|
|
||||||
ERROR_MSG=$(echo "$RESULT_PAGE" | grep -oP 'toast-body">[^<]*<[^>]*>[^<]*' | head -1)
|
|
||||||
if [ -n "$ERROR_MSG" ]; then
|
|
||||||
fail "Encoding failed: $ERROR_MSG"
|
|
||||||
else
|
|
||||||
fail "No download link found in encode result"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Encode/Decode (no image tools)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Admin encode/decode (not logged in)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 5: Create Regular User
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[5/9] Create Regular User${NC}"
|
|
||||||
|
|
||||||
if [ "$ADMIN_LOGGED_IN" = true ]; then
|
|
||||||
# Check if there's a user management page
|
|
||||||
USERS_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/users" 2>/dev/null || echo "")
|
|
||||||
|
|
||||||
if echo "$USERS_PAGE" | grep -qi "user\|create\|add"; then
|
|
||||||
CSRF_TOKEN=$(echo "$USERS_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$RESPONSE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/users/create" \
|
|
||||||
-d "username=$REGULAR_USER" \
|
|
||||||
-d "password=$REGULAR_PASS" \
|
|
||||||
-d "password_confirm=$REGULAR_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "200" ]; then
|
|
||||||
pass "Regular user created"
|
|
||||||
USER_CREATED=true
|
|
||||||
else
|
|
||||||
# Try alternate endpoint
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$RESPONSE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/register" \
|
|
||||||
-d "username=$REGULAR_USER" \
|
|
||||||
-d "password=$REGULAR_PASS" \
|
|
||||||
-d "password_confirm=$REGULAR_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "200" ]; then
|
|
||||||
pass "Regular user created (via register)"
|
|
||||||
USER_CREATED=true
|
|
||||||
else
|
|
||||||
fail "Failed to create regular user"
|
|
||||||
USER_CREATED=false
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "User creation (no user management page)"
|
|
||||||
USER_CREATED=false
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "User creation (admin not logged in)"
|
|
||||||
USER_CREATED=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 6: Regular User Login & Encode/Decode
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[6/9] Regular User Workflow${NC}"
|
|
||||||
|
|
||||||
if [ "$USER_CREATED" = true ]; then
|
|
||||||
# Logout admin first (get fresh session)
|
|
||||||
curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/logout" >/dev/null
|
|
||||||
|
|
||||||
# Login as regular user
|
|
||||||
LOGIN_PAGE=$(curl $CURL_OPTS -s -c "$COOKIE_JAR_USER" "$BASE_URL/login")
|
|
||||||
CSRF_TOKEN=$(echo "$LOGIN_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$RESPONSE" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR_USER" -c "$COOKIE_JAR_USER" \
|
|
||||||
-X POST "$BASE_URL/login" \
|
|
||||||
-d "username=$REGULAR_USER" \
|
|
||||||
-d "password=$REGULAR_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN" \
|
|
||||||
-L)
|
|
||||||
|
|
||||||
USER_HOMEPAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR_USER" -c "$COOKIE_JAR_USER" "$BASE_URL/")
|
|
||||||
if echo "$USER_HOMEPAGE" | grep -qi "logout"; then
|
|
||||||
pass "Regular user login successful"
|
|
||||||
|
|
||||||
# Try encode/decode as regular user
|
|
||||||
if [ -f "$TEST_IMAGE" ]; then
|
|
||||||
ENCODE_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR_USER" "$BASE_URL/encode")
|
|
||||||
CSRF_TOKEN=$(echo "$ENCODE_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$ENCODED_IMAGE_USER" -w "%{http_code}" \
|
|
||||||
-b "$COOKIE_JAR_USER" \
|
|
||||||
-X POST "$BASE_URL/encode" \
|
|
||||||
-F "reference_photo=@$TEST_IMAGE" \
|
|
||||||
-F "carrier=@$TEST_IMAGE" \
|
|
||||||
-F "message=User smoke test" \
|
|
||||||
-F "passphrase=user test phrase" \
|
|
||||||
-F "pin=567890" \
|
|
||||||
-F "csrf_token=$CSRF_TOKEN")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "200" ] && [ -s "$ENCODED_IMAGE_USER" ] && file "$ENCODED_IMAGE_USER" | grep -qi "image\|PNG"; then
|
|
||||||
pass "Regular user encoding works"
|
|
||||||
else
|
|
||||||
fail "Regular user encoding failed"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
fail "Regular user login failed"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Regular user workflow (user not created)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 7: Password Recovery QR
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[7/9] Password Recovery QR${NC}"
|
|
||||||
|
|
||||||
# Re-login as admin
|
|
||||||
LOGIN_PAGE=$(curl $CURL_OPTS -s -c "$COOKIE_JAR" "$BASE_URL/login")
|
|
||||||
CSRF_TOKEN=$(echo "$LOGIN_PAGE" | grep -oP 'name="csrf_token"[^>]*value="\K[^"]+' || echo "")
|
|
||||||
|
|
||||||
curl $CURL_OPTS -s -o /dev/null \
|
|
||||||
-b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
|
||||||
-X POST "$BASE_URL/login" \
|
|
||||||
-d "username=$ADMIN_USER" \
|
|
||||||
-d "password=$ADMIN_PASS" \
|
|
||||||
-d "csrf_token=$CSRF_TOKEN" \
|
|
||||||
-L
|
|
||||||
|
|
||||||
# Check for recovery QR endpoint
|
|
||||||
RECOVERY_PAGE=$(curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/recovery" 2>/dev/null ||
|
|
||||||
curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/settings" 2>/dev/null ||
|
|
||||||
curl $CURL_OPTS -s -b "$COOKIE_JAR" "$BASE_URL/account" 2>/dev/null || echo "")
|
|
||||||
|
|
||||||
if echo "$RECOVERY_PAGE" | grep -qi "recovery\|qr\|backup"; then
|
|
||||||
pass "Recovery page accessible"
|
|
||||||
|
|
||||||
# Try to get QR image
|
|
||||||
QR_URL=$(echo "$RECOVERY_PAGE" | grep -oP 'src="[^"]*qr[^"]*"' | head -1 | sed 's/src="//;s/"$//' || echo "")
|
|
||||||
|
|
||||||
if [ -n "$QR_URL" ]; then
|
|
||||||
if [[ "$QR_URL" != http* ]]; then
|
|
||||||
QR_URL="$BASE_URL$QR_URL"
|
|
||||||
fi
|
|
||||||
|
|
||||||
HTTP_CODE=$(curl $CURL_OPTS -s -o "$QR_IMAGE" -w "%{http_code}" -b "$COOKIE_JAR" "$QR_URL")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "200" ] && [ -s "$QR_IMAGE" ]; then
|
|
||||||
if file "$QR_IMAGE" | grep -qi "image\|PNG"; then
|
|
||||||
pass "Recovery QR code generated"
|
|
||||||
else
|
|
||||||
fail "QR endpoint returned non-image"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
fail "Failed to fetch QR code"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "QR code URL not found in page"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Password recovery (no recovery page found)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 8: System Health
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[8/9] System Health${NC}"
|
|
||||||
|
|
||||||
if [ "$DOCKER_MODE" = true ]; then
|
|
||||||
# Docker mode: skip SSH/systemd checks, just verify container is responding
|
|
||||||
HEALTH_CHECK=$(curl $CURL_OPTS -s -o /dev/null -w "%{http_code}" "$BASE_URL/" 2>/dev/null || echo "000")
|
|
||||||
if [ "$HEALTH_CHECK" = "200" ] || [ "$HEALTH_CHECK" = "302" ]; then
|
|
||||||
pass "Docker container healthy (HTTP $HEALTH_CHECK)"
|
|
||||||
else
|
|
||||||
fail "Docker container not responding (HTTP $HEALTH_CHECK)"
|
|
||||||
fi
|
|
||||||
skip "CLI check (Docker mode)"
|
|
||||||
skip "Service check (Docker mode)"
|
|
||||||
else
|
|
||||||
# Pi mode: check via SSH
|
|
||||||
# Check if stegasoo CLI works via SSH (optional)
|
|
||||||
if command -v sshpass &>/dev/null; then
|
|
||||||
CLI_VERSION=$(sshpass -p 'stegasoo' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
|
||||||
admin@$PI_IP "stegasoo --version" 2>/dev/null || echo "")
|
|
||||||
|
|
||||||
if [ -n "$CLI_VERSION" ]; then
|
|
||||||
pass "CLI accessible: $CLI_VERSION"
|
|
||||||
else
|
|
||||||
skip "CLI check (SSH failed or CLI not in PATH)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "CLI check (sshpass not installed)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check service status via SSH
|
|
||||||
if command -v sshpass &>/dev/null; then
|
|
||||||
SERVICE_STATUS=$(sshpass -p 'stegasoo' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
|
||||||
admin@$PI_IP "systemctl is-active stegasoo" 2>/dev/null || echo "unknown")
|
|
||||||
|
|
||||||
if [ "$SERVICE_STATUS" = "active" ]; then
|
|
||||||
pass "Stegasoo service is active"
|
|
||||||
else
|
|
||||||
fail "Stegasoo service status: $SERVICE_STATUS"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
skip "Service check (sshpass not installed)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Test 9: Cleanup
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}[9/9] Cleanup${NC}"
|
|
||||||
|
|
||||||
# Just verify we can still access the site
|
|
||||||
if curl $CURL_OPTS -s -o /dev/null -w "%{http_code}" "$BASE_URL" | grep -q "200\|302"; then
|
|
||||||
pass "Site still accessible after tests"
|
|
||||||
else
|
|
||||||
fail "Site not accessible after tests"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Summary
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
TOTAL=$((TESTS_PASSED + TESTS_FAILED))
|
|
||||||
|
|
||||||
if [ $TESTS_FAILED -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}${BOLD}All tests passed!${NC} ($TESTS_PASSED/$TOTAL)"
|
|
||||||
else
|
|
||||||
echo -e "${RED}${BOLD}Some tests failed${NC} ($TESTS_PASSED passed, $TESTS_FAILED failed)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "Target: $BASE_URL"
|
|
||||||
echo -e "Admin user: $ADMIN_USER"
|
|
||||||
echo -e "Regular user: $REGULAR_USER"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
exit $TESTS_FAILED
|
|
||||||
Reference in New Issue
Block a user