Integrate reviewer tool as Flask Blueprint#39
Conversation
There was a problem hiding this comment.
Pull request overview
This PR integrates a reviewer/moderation tool as a Flask Blueprint, providing a web interface for administrators and reviewers to approve or reject pending crackme and solution submissions. The implementation includes a separate authentication system for reviewers, comprehensive logging, Discord notifications for approved content, and admin-only features for managing users and content.
Key Changes
- Integrated reviewer tool as a Flask Blueprint at
/reviewwith separate authentication from main site users - Split Discord webhooks into public (approved items) and private (pending items/logs) channels
- Fixed session management to preserve reviewer sessions when users log out from the main site
- Added comprehensive access controls distinguishing between reviewer and admin permissions
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| review/routes.py | Core reviewer Blueprint with authentication, approval/rejection workflows, and admin features |
| review/logger.py | Logging infrastructure for reviewer operations to file and Discord |
| review/templates/ | HTML templates for reviewer interface (login, dashboard, review pages, admin tools) |
| script/generate_reviewer_password_hash.py | Utility to generate password hashes for reviewer accounts |
| script/validate.py | Deleted - functionality moved into Blueprint |
| script/delete.py | Deleted - functionality moved into Blueprint |
| app/init.py | Registers reviewer Blueprint and initializes its configuration |
| app/services/session.py | Modified to clear only main site session keys, preserving reviewer sessions |
| app/services/discord.py | Split into public/private webhook support |
| app/controllers/login.py | Updated to use selective session clearing |
| config/config.json.example | Added reviewer configuration options |
| README.md | Comprehensive documentation for reviewer tool setup and usage |
| .gitignore | Added reviewer log and credentials file |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return False, "Crackme file not found in tmp directory" | ||
|
|
||
| # Create temp file for zipping | ||
| temp_filename = os.path.join(CRACKMESONE_DIR, filename) |
There was a problem hiding this comment.
The filename extracted from file_loc is used directly in os.path.join without re-validation. While secure_filename is used during upload, this creates a defensive programming issue. If the filesystem were manipulated directly or the database corrupted, this could theoretically lead to path traversal. Consider re-applying secure_filename or validating that the filename contains no path separators before using it.
1f27f2b to
e1659f1
Compare
Integrates the reviewer tool from crackmesone_reviewer_tool repository as a Flask Blueprint at /review, sharing the same MongoDB connection and session management with the main site. Key changes: - Added review/ folder with Flask Blueprint for content moderation - Reviewer authentication uses Flask sessions (separate from main site) - Integrated delete.py and validate.py scripts directly into routes - Renamed endpoints for clarity (delc→rejectcrackme, vals→approvesolution) - Fixed security vulnerabilities: - Changed /deleteuser from @token_required to @admin_required - Fixed NoSQL regex injection with re.escape() in 6 locations - Fixed argument injection in zip commands with -- separator - All state-changing actions now require POST with CSRF tokens - Added Discord notifications for approved crackmes/solutions - Added comprehensive logging for all reviewer operations - Updated README with reviewer tool configuration documentation Access control: - Reviewers: approve/reject pending submissions - Admins: all reviewer actions + delete approved content, manage users Configuration: - config.json: Reviewer.Enabled, Reviewer.PasswordSalt - review/users.json: Reviewer credentials (username, password_hash, is_admin) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
e1659f1 to
f37c51b
Compare
Major improvements: - Extract helper functions to eliminate code duplication: - get_current_reviewer() for unified auth checks - find_pending_file() for file lookup across crackmes/solutions - send_user_notification() for in-app notifications - post_discord_notification() for webhook calls - create_password_protected_zip() for archive creation - parse_pending_filename() for consistent filename parsing - Add comprehensive docstrings to all functions with Args/Returns - Organize code into clear sections with header dividers: - Configuration and Constants - Authentication Helpers - CSRF Protection - File and Path Helpers - Database Helpers - Notification Helpers - Archive Helpers - Pending Submission Operations - Approved Content Deletion - User Account Management - Route Handlers - Rename functions for clarity (e.g., get_list_review_solution → get_pending_solutions) - Add ARCHIVE_PASSWORD and REVIEWER_CSRF_KEY constants - Consolidate duplicate Discord webhook and notification code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move -- separator after archive name to correctly protect filenames while keeping the archive path in proper position. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, the solution count was only decremented if the zip file existed on disk. Now it decrements as long as the solution exists in the database, regardless of file presence. Fixes #37 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Restore the ✅ and ❌ emojis in the status field for success/failed operations to match the original reviewer tool styling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The color logic only checked for 'validate' prefix but we use 'approve_crackme' and 'approve_solution' as operation types. Added check for 'approve' prefix to use green color. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
crackmesone_reviewer_toolrepository as a Flask Blueprint at/reviewChanges
New Features
review/folder with Flask Blueprint for content moderationdelete.pyandvalidate.pyscripts directly into routes/delc→/rejectcrackme,/vals→/approvesolution, etc.)Security Fixes
/deleteuserfrom@token_requiredto@admin_requiredre.escape()in 6 locations--separatorAccess Control
Configuration
config.json: AddedReviewer.EnabledandReviewer.PasswordSaltreview/users.json: Reviewer credentials (username, password_hash, is_admin)script/generate_reviewer_password_hash.pyfor creating password hashesTest plan
Closes #23
🤖 Generated with Claude Code