Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .coverage
Binary file not shown.
2 changes: 0 additions & 2 deletions docs/step3/2_DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ LOG_LEVEL=INFO
LOG_FILE=app.log
LOG_FORMAT=%(levelname)-8s %(asctime)s %(name)s.%(module)s:%(lineno)s | %(message)s
LOG_BODY=false
LOGGER_TYPE=development

# JWT Configuration
ALGORITHM=HS256
Expand Down Expand Up @@ -362,7 +361,6 @@ ALLOWED_ORIGINS=["https://yourdomain.com", "https://api.yourdomain.com"]

# Enable production logging
LOG_LEVEL=INFO
LOGGER_TYPE=production
```

## 📊 Monitoring & Logging
Expand Down
18 changes: 8 additions & 10 deletions docs/step3/3_LOGGING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ Configure logging through environment variables in your `.env` file:
# Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO

# Logger type: development, production, test
LOGGER_TYPE=development

# Log file path (relative to project root)
LOG_FILE=logs/app.log

Expand All @@ -46,19 +43,20 @@ The system supports five log levels with hierarchical filtering:

**Example**: If `LOG_LEVEL=INFO`, only INFO, WARNING, ERROR, and CRITICAL messages will be displayed. DEBUG messages will be suppressed.

### Logger Types
### Automatic Environment-Based Logging

The logging system automatically adapts its output format based on the `ENVIRONMENT` setting:

#### Development Logger (`LOGGER_TYPE=development`)
- Human-readable format
- Colored console output
#### Development Environment (`ENVIRONMENT=development`)
- Human-readable format with colors
- Includes module and line numbers
- Suitable for local development

```
2024-01-15 10:30:45 | INFO | src.services.recipe_service:45 | Recipe created successfully
```

#### Production Logger (`LOGGER_TYPE=production`)
#### Production/Testing Environment (`ENVIRONMENT=production` or `ENVIRONMENT=testing`)
- Structured JSON format
- Machine-readable logs
- Includes comprehensive context
Expand Down Expand Up @@ -365,7 +363,7 @@ logger.info("User authenticated", extra={
- Check file permissions

#### 3. JSON Format Not Working
- Set `LOGGER_TYPE=production`
- Set `ENVIRONMENT=production` or `ENVIRONMENT=testing`
- Check for JSON serialization errors
- Verify all extra data is JSON-serializable

Expand All @@ -384,7 +382,7 @@ logger = get_logger(__name__)
# Log current configuration
logger.info("Logging configuration", extra={
"log_level": settings.LOG_LEVEL,
"logger_type": settings.LOGGER_TYPE,
"environment": settings.ENVIRONMENT,
"log_file": settings.LOG_FILE
})
```
Expand Down
179 changes: 179 additions & 0 deletions docs/step3/5_AUTHENTICATION_BYPASS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Authentication Bypass for Development

This document explains how to use the authentication bypass feature for development purposes.

## Overview

The authentication bypass feature allows developers to skip JWT token validation during development by configuring a specific email address. This is useful for:

- Testing API endpoints without generating JWT tokens
- Development and debugging
- Automated testing scenarios

## Configuration

### Environment Variable

Set the `AUTH_BYPASS_EMAIL` environment variable to enable bypass:

```bash
# In your .env file or environment
AUTH_BYPASS_EMAIL=dev@example.com
```

### Example .env Configuration

```env
# Authentication Bypass for Development
# Set to a valid email address to bypass authentication during development
# Leave empty, unset, or set to None/null to use normal JWT authentication
AUTH_BYPASS_EMAIL=dev@example.com
```

### Development vs Production Behavior

**Development Mode:**
```env
AUTH_BYPASS_EMAIL=developer@example.com
```
- ✅ Authentication bypass is **enabled**
- ✅ No JWT token required for protected endpoints
- ✅ User is automatically authenticated using the specified email

**Production Mode:**
```env
# Any of these configurations will disable bypass:
AUTH_BYPASS_EMAIL=
AUTH_BYPASS_EMAIL=None
AUTH_BYPASS_EMAIL=null
# Or simply don't set the variable at all
```
- ❌ Authentication bypass is **disabled**
- ✅ Normal JWT authentication is required
- ✅ All protected endpoints require valid Authorization header

## How It Works

1. **Bypass Check**: When a protected endpoint is accessed, the system first checks if `AUTH_BYPASS_EMAIL` is configured
2. **User Lookup**: If bypass is enabled, the system looks up the user by the configured email address
3. **Authentication**: The user is automatically authenticated without requiring a JWT token
4. **Normal Flow**: If bypass is disabled, normal JWT authentication is used

## Usage

### With Bypass Enabled

```bash
# No Authorization header needed
curl -X GET http://localhost:5000/api/recipes
```

### With Bypass Disabled (Normal Authentication)

```bash
# Requires valid JWT token
curl -X GET http://localhost:5000/api/recipes \
-H "Authorization: Bearer your-jwt-token-here"
```

## Implementation Details

### New Decorator

The system introduces a new `@auth_required` decorator that replaces `@jwt_required()`:

```python
from src.utils.auth_decorators import auth_required

@recipe_bp.route("/recipes", methods=["GET"])
@auth_required
def get_recipes():
user_id = g.current_user_id # Available in Flask's g object
user_email = g.current_user_email # Available in Flask's g object
# ... rest of the function
```

### User Information Access

When using the bypass, user information is available in Flask's `g` object:

- `g.current_user_id`: The user's ID
- `g.current_user_email`: The user's email address

## Security Considerations

⚠️ **Important Security Notes:**

1. **Development Only**: This feature should only be used in development environments
2. **Never in Production**: Never set `AUTH_BYPASS_EMAIL` in production
3. **Valid User Required**: The bypass email must correspond to an existing user in the database
4. **Environment Separation**: Use different environment configurations for development and production

## Troubleshooting

### Common Issues

1. **Bypass User Not Found**
```
Error: Bypass user not found: dev@example.com
```
**Solution**: Ensure the email address exists in the user database

2. **Database Connection Issues**
```
Error: Bypass authentication failed: [database error]
```
**Solution**: Check database connectivity and user table

3. **Configuration Not Loaded**
```
Error: Invalid authentication credentials
```
**Solution**: Verify `AUTH_BYPASS_EMAIL` is properly set in environment

### Debugging

Enable debug logging to see bypass activity:

```python
import logging
logging.getLogger('src.utils.auth_decorators').setLevel(logging.DEBUG)
```

## Migration from JWT-Only

To migrate existing routes from JWT-only to bypass-enabled:

1. **Replace Decorator**:
```python
# Before
@jwt_required()

# After
@auth_required
```

2. **Update User ID Access**:
```python
# Before
user_id = int(get_jwt_identity())

# After
user_id = g.current_user_id
```

3. **Add Import**:
```python
from src.utils.auth_decorators import auth_required
from flask import g
```

## Testing

Use the provided test script to verify bypass functionality:

```bash
python test_auth_bypass.py
```

This will test both bypass-enabled and normal authentication modes.
147 changes: 147 additions & 0 deletions docs/step3/6_MANUAL_TESTING_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Manual Testing Guide for Authentication Bypass

## 🧪 Testing Development vs Production Modes

### **Test 1: Development Mode (Bypass Enabled)**

**Step 1: Start Server with Bypass**
```bash
cd /home/bitcot/Desktop/Recipe-Manager

AUTH_BYPASS_EMAIL=test@example.com \
SECRET_KEY=test-secret-key \
ALLOWED_ORIGINS='["http://localhost:3000"]' \
ENVIRONMENT=development \
python -m src.api.app
```

**Step 2: Test Endpoints (in new terminal)**
```bash
# These should work WITHOUT any auth headers
curl -X GET http://localhost:5000/api/recipes
curl -X GET http://localhost:5000/api/auth/me

# Expected Results:
# ✅ Status: 200 OK
# ✅ No Authorization header required
# ✅ Server logs show "Bypassing authentication for development"
```

**Step 3: Test with Auth Header (should still work)**
```bash
# Even with auth header, bypass should work
curl -X GET http://localhost:5000/api/recipes \
-H "Authorization: Bearer fake-token"

# Expected: 200 OK (bypass takes precedence)
```

---

### **Test 2: Production Mode (Bypass Disabled)**

**Step 1: Stop Server and Restart Without Bypass**
```bash
# Stop server (Ctrl+C) and restart without AUTH_BYPASS_EMAIL
SECRET_KEY=test-secret-key \
ALLOWED_ORIGINS='["http://localhost:3000"]' \
ENVIRONMENT=production \
python -m src.api.app
```

**Step 2: Test Endpoints Without Auth (should fail)**
```bash
# These should FAIL without auth headers
curl -X GET http://localhost:5000/api/recipes
curl -X GET http://localhost:5000/api/auth/me

# Expected Results:
# ❌ Status: 401 Unauthorized
# ❌ Error: "Authorization token required"
```

**Step 3: Test with Valid JWT Token**
```bash
# First, login to get JWT token
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "your-password-here"
}'

# Then use the JWT token from response
curl -X GET http://localhost:5000/api/recipes \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"

# Expected: 200 OK
```

---

### **Test 3: Automated Testing**

**Run the automated test script:**
```bash
python3 test_production_vs_development.py
```

This will automatically test both modes and show you the results.

---

## 📊 Expected Results Summary

| **Mode** | **AUTH_BYPASS_EMAIL** | **No Auth Header** | **With Auth Header** | **Expected Behavior** |
|----------|----------------------|-------------------|---------------------|---------------------|
| **Development** | `test@example.com` | ✅ 200 OK | ✅ 200 OK | Bypass works |
| **Production** | Not set | ❌ 401 Unauthorized | ✅ 200 OK (if valid JWT) | Normal JWT auth |

---

## 🔍 What to Look For

### **Development Mode (Bypass Enabled)**
- ✅ All requests work without Authorization header
- ✅ Server logs show "Bypassing authentication for development"
- ✅ User ID 5 (test@example.com) is used automatically
- ✅ No JWT token validation occurs

### **Production Mode (Bypass Disabled)**
- ❌ Requests without Authorization header fail with 401
- ✅ Requests with valid JWT token work normally
- ✅ Normal JWT authentication flow
- ✅ No bypass messages in logs

---

## 🚨 Troubleshooting

### **If Development Mode Fails:**
1. Check that `AUTH_BYPASS_EMAIL=test@example.com` is set
2. Verify user `test@example.com` exists in database
3. Check server logs for error messages

### **If Production Mode Fails:**
1. Ensure `AUTH_BYPASS_EMAIL` is not set
2. Verify JWT token is valid and not expired
3. Check that user exists and is active

### **Common Issues:**
- **Port 5000 in use**: Kill existing processes with `pkill -f "python.*src.api.app"`
- **Database connection**: Ensure database is running and accessible
- **User not found**: Verify bypass user exists in database

---

## 🎯 Success Criteria

Your authentication bypass is working correctly if:

1. **Development Mode**: All endpoints work without auth headers
2. **Production Mode**: All endpoints require valid JWT tokens
3. **Security**: Bypass only works when `AUTH_BYPASS_EMAIL` is set
4. **Logging**: Appropriate bypass messages appear in logs
5. **User Context**: Correct user is used when bypass is enabled

If all these criteria are met, your implementation is working perfectly! 🎉
Loading