Implement MVP: Anonymous feedback submission (User Story 1)
Complete implementation of Phase 1-3 (64 tasks): - Phase 1: Project setup with Flask, pytest, configuration - Phase 2: Core infrastructure (auth, models, services, testing) - Phase 3: Anonymous feedback submission with file uploads Features: - Anonymous feedback submission (text and/or up to 3 file attachments) - Multi-language support (any language accepted) - File validation (type, size) and virus scanning (ClamAV) - Product management with active/archived status - File-based storage with YAML metadata - User authentication system (Flask-Login) - CSRF protection and rate limiting - Test coverage: 10 passing tests (contract + integration) Security: - No IP address logging (FR-055 compliance) - File type whitelist and size limits (10MB max) - Virus scanning with graceful degradation - Filename sanitization and secure storage Test Results: - 8 contract tests passed - 2 integration tests passed - End-to-end workflow verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
"""Authentication service"""
|
||||
import bcrypt
|
||||
from app.models.user import User
|
||||
|
||||
|
||||
def verify_credentials(username, password):
|
||||
"""Verify username and password
|
||||
|
||||
Args:
|
||||
username: Username to check
|
||||
password: Plain text password to verify
|
||||
|
||||
Returns:
|
||||
User or None: User object if credentials valid, None otherwise
|
||||
"""
|
||||
if not username or not password:
|
||||
return None
|
||||
|
||||
user = User.get_by_username(username)
|
||||
|
||||
if not user or not user.is_active:
|
||||
return None
|
||||
|
||||
if user.check_password(password):
|
||||
return user
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def hash_password(password):
|
||||
"""Hash password using bcrypt
|
||||
|
||||
Args:
|
||||
password: Plain text password
|
||||
|
||||
Returns:
|
||||
str: Hashed password
|
||||
"""
|
||||
return User.hash_password(password)
|
||||
|
||||
|
||||
def check_password(password, password_hash):
|
||||
"""Check password against hash
|
||||
|
||||
Args:
|
||||
password: Plain text password
|
||||
password_hash: Bcrypt hash to check against
|
||||
|
||||
Returns:
|
||||
bool: True if password matches, False otherwise
|
||||
"""
|
||||
return bcrypt.checkpw(password.encode('utf-8'), password_hash.encode('utf-8'))
|
||||
Reference in New Issue
Block a user