Skip to content
Open

Dev #19

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
56 changes: 31 additions & 25 deletions .github/workflows/security_scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
actions: read
contents: read
pull-requests: write

steps:
- name: 1. Checkout repository code
uses: actions/checkout@v4
Expand All @@ -35,15 +35,15 @@ jobs:
working-directory: ./backend
run: |
echo "Running Bandit security scan..."

if bandit -r . -f json -o bandit-results.json --configfile pyproject.toml; then
echo "BANDIT_PASSED=true" >> $GITHUB_ENV
echo "✅ No security issues found by Bandit"
else
echo "BANDIT_PASSED=false" >> $GITHUB_ENV
echo "⚠️ Bandit found security issues"
fi

bandit -r . -f sarif -o bandit-results.sarif --configfile pyproject.toml || true
continue-on-error: true

Expand All @@ -53,51 +53,57 @@ jobs:
with:
sarif_file: backend/bandit-results.sarif
continue-on-error: true

- name: 6. Create Security Summary
if: github.event_name == 'pull_request'
working-directory: ./backend
run: |
cat > ../security-report.md << 'EOL'
## 🔒 Security Scan Results

EOL

# Check actual issue count from JSON results instead of exit code
ACTUAL_ISSUES=0
if [ -f bandit-results.json ]; then
ACTUAL_ISSUES=$(python3 -c "import json; data=json.load(open('bandit-results.json')); metrics=data.get('metrics',{}); print(metrics.get('SEVERITY.HIGH',0) + metrics.get('SEVERITY.MEDIUM',0) + metrics.get('SEVERITY.LOW',0))" 2>/dev/null || echo "0")
fi

if [[ "${{ env.BANDIT_PASSED }}" == "true" ]]; then
if [[ "$ACTUAL_ISSUES" == "0" ]]; then
cat >> ../security-report.md << 'EOL'
### ✅ Bandit: **Passed**

No security issues found. Your code passed all security checks! 🎉

EOL
else
cat >> ../security-report.md << 'EOL'
### ⚠️ Bandit: **Security Issues Found**

EOL

# Parse and display results if file exists
if [ -f bandit-results.json ]; then
echo '<details><summary>Click to view security findings</summary>' >> ../security-report.md
echo '' >> ../security-report.md
echo '```' >> ../security-report.md

python3 << 'PYTHON_SCRIPT' >> ../security-report.md 2>/dev/null || echo "Could not parse results" >> ../security-report.md
import json
import sys

try:
with open('bandit-results.json', 'r') as f:
data = json.load(f)

# Print metrics
metrics = data.get('metrics', {})
total_issues = sum([
metrics.get('SEVERITY.HIGH', 0),
metrics.get('SEVERITY.MEDIUM', 0),
metrics.get('SEVERITY.LOW', 0)
])

print(f'📊 Summary:')
print(f'Total issues: {total_issues}')
print(f'Files with issues: {metrics.get("files_with_issues", 0)}')
Expand All @@ -106,13 +112,13 @@ jobs:
print(f'🟡 Medium severity: {metrics.get("SEVERITY.MEDIUM", 0)}')
print(f'🟢 Low severity: {metrics.get("SEVERITY.LOW", 0)}')
print()

# Group results by severity
results = data.get('results', [])
high = [r for r in results if r['issue_severity'] == 'HIGH']
medium = [r for r in results if r['issue_severity'] == 'MEDIUM']
low = [r for r in results if r['issue_severity'] == 'LOW']

# Display high severity first (up to 5)
if high:
print('🔴 HIGH SEVERITY ISSUES:')
Expand All @@ -124,7 +130,7 @@ jobs:
if len(high) > 5:
print(f" ... and {len(high) - 5} more high severity issues")
print()

# Display medium severity (up to 3)
if medium:
print('🟡 MEDIUM SEVERITY ISSUES:')
Expand All @@ -135,15 +141,15 @@ jobs:
if len(medium) > 3:
print(f" ... and {len(medium) - 3} more medium severity issues")
print()
# Display low severity count only

# Display low severity count only if there are issues
if low:
print(f'🟢 LOW SEVERITY: {len(low)} issues found')

except Exception as e:
print(f'Error parsing bandit results: {str(e)}')
PYTHON_SCRIPT

echo '```' >> ../security-report.md
echo '</details>' >> ../security-report.md
echo '' >> ../security-report.md
Expand All @@ -152,15 +158,15 @@ jobs:
echo 'Could not find detailed results file.' >> ../security-report.md
fi
fi

cat >> ../security-report.md << 'EOL'

---
*Security scans help identify potential vulnerabilities in your code. [Learn more about Bandit](https://bandit.readthedocs.io/)*

<!-- security-scan-comment-marker -->
EOL

- name: 7. Post PR Comment
if: github.event_name == 'pull_request'
uses: peter-evans/create-or-update-comment@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ nginx/logs/
backend/.coverage
backend/context/
backend/certgames.egg-info
conf/nginx/logs/
98 changes: 51 additions & 47 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
MAKEFLAGS += --no-print-directory

DEV_COMPOSE_FILE := docker-compose.yml.dev
PROD_COMPOSE_FILE := docker-compose.yml.prod

ADMIN_APP_DIR := frontend/admin-app
USER_APP_DIR := frontend/user-app

.PHONY: help logs admin admin-up admin-down build-dev dev-up dev-down \
admin-logs backend-logs frontend-logs user-logs clean-docker \
Expand Down Expand Up @@ -162,31 +164,6 @@ define ASCII_LINT
endef


# ==================== Database Seeding ====================
seed-content:
@echo "\033[1;3;4;96m======== Seeding Content Data ========\033[0m"
@cd backend && python devtools/seed/seed_content_data.py --questions=100 --days=90 --answers=5000
@echo "\033[1;92m✅ Content data seeded successfully!\033[0m"
$(call ASCII_DOCKER)

seed-content-clear:
@echo "\033[1;3;4;96m======== Clearing and Reseeding Content Data ========\033[0m"
@cd backend && python devtools/seed/seed_content_data.py --clear --questions=100 --days=90 --answers=5000
@echo "\033[1;92m✅ Content data cleared and reseeded!\033[0m"
$(call ASCII_DOCKER)

seed-content-dev:
@echo "\033[1;3;4;96m======== Seeding Content Data (Development) ========\033[0m"
@cd backend && python devtools/seed/seed_content_data.py --questions=50 --days=30 --answers=2000
@echo "\033[1;92m✅ Development content data seeded!\033[0m"
$(call ASCII_DOCKER)

seed-content-production:
@echo "\033[1;3;4;96m======== Seeding Content Data (Production-Like) ========\033[0m"
@cd backend && python devtools/seed/seed_content_data.py --clear --questions=200 --days=120 --answers=10000
@echo "\033[1;92m✅ Production-like content data seeded!\033[0m"
$(call ASCII_DOCKER)

# ==================== Help Command ====================
help:
@echo "\033[1;91m \033[1;92mC\033[1;93me\033[1;94mr\033[1;95mt\033[1;96mG\033[1;91ma\033[1;92mm\033[1;93me\033[1;94ms\033[0m \033[1;95mDocker\033[0m \033[1;96mManagement\033[0m \033[1;91mCommands\033[0m "
Expand All @@ -210,8 +187,15 @@ help:
$(call ASCII_DOCKER)


# ==================== Maintenance ====================
clean-docker:
@echo "\033[1;3;4;96m======== Cleaning Docker Resources ========\033[0m"
docker system prune -f
docker image prune -f
@echo "\033[1;92m✅ Docker cleanup completed!\033[0m"
$(call ASCII_DOCKER)

prune:
nuke-docker:
@echo "\033[1;3;4;96m======== Prune images/volumes/cache ========\033[0m"
docker system prune -a --volumes -f
$(call ASCII_DOCKER)
Expand All @@ -234,48 +218,34 @@ dev-down:


# ==================== Logging Commands ====================
logs:
@echo "\033[1;3;4;96m======= Viewing Dev Logs ========\033[0m"
@docker compose -f docker-compose.yml.dev logs -f backend redis celery admin_frontend
$(call ASCII_LOGS)

dev-logs:
@echo "\033[1;3;4;96m======== Viewing Full dev Logs ========\033[0m"
docker compose -f docker-compose.yml.dev logs -f
$(call ASCII_LOGS)

backend-logs:
dev-backend-logs:
@echo "\033[1;3;4;96m======== Viewing Backend Service Logs ========\033[0m"
docker compose -f docker-compose.yml.dev logs -f backend_service
$(call ASCII_LOGS)

frontend-logs:
dev-admin-logs:
@echo "\033[1;3;4;96m======== Viewing dev Frontend Logs ========\033[0m"
docker compose -f docker-compose.yml.dev logs -f admin_frontend
docker compose -f docker-compose.yml.dev logs -f admin_frontend
$(call ASCII_LOGS)

user-logs:
dev-user-logs:
@echo "\033[1;3;4;96m======== Viewing User Frontend Logs ========\033[0m"
docker compose -f docker-compose.yml.dev logs -f user_frontend
$(call ASCII_LOGS)

# ==================== Maintenance ====================
clean-docker:
@echo "\033[1;3;4;96m======== Cleaning Docker Resources ========\033[0m"
docker system prune -f
docker image prune -f
@echo "\033[1;92m✅ Docker cleanup completed!\033[0m"
$(call ASCII_DOCKER)




# ==================== Frontend Admin Formatting and Linting ====================
format-admin:
@echo "Formatting admin app with Prettier..."
@cd $(ADMIN_APP_DIR) && npm run format
$(call ASCII_ASCII_LINT)

admin-check:
check-admin:
@echo "Checking admin app formatting with Prettier..."
@cd $(ADMIN_APP_DIR) && npm run format:check
$(call ASCII_ASCII_LINT)
Expand Down Expand Up @@ -303,6 +273,40 @@ types-admin:
lint-admin-full: format-check-admin lint-scss-admin lint-eslint-admin types-admin
@echo "All admin app linters passed!"
$(call ASCII_ASCII_LINT)

# ==================== Frontend User Formatting and Linting ====================
format-user:
@echo "Formatting user app with Prettier..."
@cd $(USER_APP_DIR) && npm run format
$(call ASCII_ASCII_LINT)

check-user:
@echo "Checking user app formatting with Prettier..."
@cd $(USER_APP_DIR) && npm run format:check
$(call ASCII_ASCII_LINT)

scss-user:
@echo "Linting user app SCSS with Stylelint..."
@cd $(USER_APP_DIR) && npm run lint:scss
$(call ASCII_ASCII_LINT)

scss-fix:
@echo "Linting --fix user app SCSS with Stylelint..."
@cd $(USER_APP_DIR) && npm run lint:scss:fix
$(call ASCII_ASCII_LINT)

lint-user:
@echo "Linting user app TypeScript/React with ESLint..."
@cd $(USER_APP_DIR) && npm run lint:eslint
$(call ASCII_ASCII_LINT)

# ==================== Frontend User Formatting and Linting ====================
types-user:
@echo "Type checking user app TypeScript with tsc..."
@cd $(USER_APP_DIR) && npm run lint:types
$(call ASCII_ASCII_LINT)

lint-user-full: format-check-user lint-scss-user lint-eslint-user types-user
@echo "All user app linters passed!"
$(call ASCII_ASCII_LINT)


25 changes: 0 additions & 25 deletions backend/TODO.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
# CertGames API TODO:

1.) Convert all model magic strings to Enums
- Models TODO:
- Admin:
- DatabaseMetrics.py
- EndpointMetrics.py
- ErrorLog.py
- WebVital.py
- AdminUser.py
- UserManagement.py
- AIUsageLog.py
- RequestLog.py
- SubscriptionMetrics.py
- IPBlocklist.py
- RateLimit.py
- DataRetention.py
- SecurityEvent.py
- TestingMetrics.py
- DailyMetrics.py
- Domains:
- Achievement.py
- User.py
- SupportThread.py
- FreemiumUsage.py
- NewsletterCampaign.py
-----
2.) Migrate Achievements to v2
---
3.) Add a rating system for daily questions
Expand Down
Loading
Loading