name: Security Scan and Upload

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  schedule:
    - cron: '0 0 * * 1'
  workflow_dispatch:

jobs:
  security-audit:
    name: Security & DefectDojo Upload
    runs-on: ubuntu-latest
    continue-on-error: true

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      # --- AUTO-SETUP PROJECT ---
      - name: Ensure DefectDojo Product Exists
        env:
          DD_URL: ${{ secrets.DD_URL }}
          DD_TOKEN: ${{ secrets.DD_TOKEN }}
          PRODUCT_NAME: ${{ github.repository }} 
          PRODUCT_TYPE_ID: 1 
        run: |
          sudo apt-get install jq -y > /dev/null
          
          echo "Checking connection to $DD_URL..."
          
          # Check if product exists - capture HTTP code to debug connection issues
          RESPONSE=$(curl --write-out "%{http_code}" --silent --output /tmp/response.json \
            -H "Authorization: Token $DD_TOKEN" \
            "$DD_URL/api/v2/products/?name=$PRODUCT_NAME")
          
          # If response is not 200, print error
          if [ "$RESPONSE" != "200" ]; then
            echo "::error::Failed to query DefectDojo. HTTP Code: $RESPONSE"
            cat /tmp/response.json
            exit 1
          fi

          COUNT=$(cat /tmp/response.json | jq -r '.count')
          
          if [ "$COUNT" = "0" ]; then
            echo "Creating product '$PRODUCT_NAME'..."
            curl -s -X POST "$DD_URL/api/v2/products/" \
              -H "Authorization: Token $DD_TOKEN" \
              -H "Content-Type: application/json" \
              -d '{ "name": "'"$PRODUCT_NAME"'", "description": "Auto-created by Gitea Actions", "prod_type": '$PRODUCT_TYPE_ID' }'
          else
            echo "Product '$PRODUCT_NAME' already exists."
          fi

      # --- 1. TRIVY (Dependencies & Misconfig) ---
      - name: Install Trivy
        run: |
          sudo apt-get install wget apt-transport-https gnupg lsb-release -y
          wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
          echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
          sudo apt-get update && sudo apt-get install trivy -y

      - name: Run Trivy (FS Scan)
        run: |
          trivy fs . --scanners vuln,misconfig --format json --output trivy-results.json --exit-code 0

      - name: Upload Trivy to DefectDojo
        env:
          DD_URL: ${{ secrets.DD_URL }}
          DD_TOKEN: ${{ secrets.DD_TOKEN }}
        run: |
          echo "Uploading Trivy results..."
          # Generate today's date in YYYY-MM-DD format
          TODAY=$(date +%Y-%m-%d)
          
          HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
            -H "Authorization: Token $DD_TOKEN" \
            -F "active=true" \
            -F "verified=true" \
            -F "scan_type=Trivy Scan" \
            -F "engagement_name=CI/CD Pipeline" \
            -F "product_name=${{ github.repository }}" \
            -F "scan_date=$TODAY" \
            -F "auto_create_context=true" \
            -F "file=@trivy-results.json")
          
          if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
            echo "::error::Upload Failed with HTTP $HTTP_CODE"
            echo "--- SERVER RESPONSE ---"
            cat response.txt
            echo "-----------------------"
            exit 1
          else
            echo "Upload Success!"
          fi

      # --- 2. GITLEAKS (Secrets) ---
      - name: Install Gitleaks
        run: |
          wget -qO gitleaks.tar.gz https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz
          tar -xzf gitleaks.tar.gz
          sudo mv gitleaks /usr/local/bin/ && chmod +x /usr/local/bin/gitleaks

      - name: Run Gitleaks
        run: gitleaks detect --source . -v --report-path gitleaks-results.json --report-format json --no-git || true

      - name: Upload Gitleaks to DefectDojo
        env:
          DD_URL: ${{ secrets.DD_URL }}
          DD_TOKEN: ${{ secrets.DD_TOKEN }}
        run: |
          echo "Uploading Gitleaks results..."  
          TODAY=$(date +%Y-%m-%d)

          HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
            -H "Authorization: Token $DD_TOKEN" \
            -F "active=true" \
            -F "verified=true" \
            -F "scan_type=Gitleaks Scan" \
            -F "engagement_name=CI/CD Pipeline" \
            -F "product_name=${{ github.repository }}" \
            -F "scan_date=$TODAY" \
            -F "auto_create_context=true" \
            -F "file=@gitleaks-results.json")

          if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
             echo "::error::Upload Failed with HTTP $HTTP_CODE"
             echo "--- SERVER RESPONSE ---"
             cat response.txt
             echo "-----------------------"
             exit 1
          else
             echo "Upload Success!"
          fi

      # --- 3. SEMGREP (SAST) ---
      - name: Install Semgrep (via pipx)
        run: |
          sudo apt-get install pipx -y
          pipx install semgrep
          # Add pipx binary path to GITHUB_PATH so next steps can see 'semgrep'
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Run Semgrep
        run: semgrep scan --config=p/security-audit --config=p/owasp-top-ten --json --output semgrep-results.json . || true

      - name: Upload Semgrep to DefectDojo
        env:
          DD_URL: ${{ secrets.DD_URL }}
          DD_TOKEN: ${{ secrets.DD_TOKEN }}
        run: |
          echo "Uploading Semgrep results..."
          TODAY=$(date +%Y-%m-%d)
          
          HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
            -H "Authorization: Token $DD_TOKEN" \
            -F "active=true" \
            -F "verified=true" \
            -F "scan_type=Semgrep JSON Report" \
            -F "engagement_name=CI/CD Pipeline" \
            -F "product_name=${{ github.repository }}" \
            -F "scan_date=$TODAY" \
            -F "auto_create_context=true" \
            -F "file=@semgrep-results.json")

          if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
             echo "::error::Upload Failed with HTTP $HTTP_CODE"
             echo "--- SERVER RESPONSE ---"
             cat response.txt
             echo "-----------------------"
             exit 1
          else
             echo "Upload Success!"
          fi