- Updated the `IntegrationService` to perform connection tests using only the API key, removing reliance on username and app password. - Simplified health check logic and improved error messaging for better clarity. - Added functionality to revoke API keys in the `WordPressIntegrationForm` component. - Enhanced site settings page with a site selector and improved integration status display. - Cleaned up unused code and improved overall structure for better maintainability.
93 lines
2.7 KiB
Markdown
93 lines
2.7 KiB
Markdown
# Site Isolation Bug - Final Fix
|
|
|
|
## Problem
|
|
All sites (5, 10, 14, 15) were showing **IDENTICAL** settings and content types instead of site-specific data. This was a **CRITICAL data isolation bug**.
|
|
|
|
## Root Cause
|
|
The `IntegrationViewSet` extends `SiteSectorModelViewSet`, which only applies site filtering if the model has **BOTH** `site` AND `sector` fields.
|
|
|
|
The `SiteIntegration` model only has a `site` field (no `sector` field), so the condition on line 231 of `base.py` was **FALSE**:
|
|
|
|
```python
|
|
if hasattr(queryset.model, 'site') and hasattr(queryset.model, 'sector'):
|
|
```
|
|
|
|
This meant the entire site filtering block was **SKIPPED**, causing ALL integrations to be returned regardless of the `?site=X` parameter.
|
|
|
|
## The Fix
|
|
|
|
### File: `/data/app/igny8/backend/igny8_core/modules/integration/views.py`
|
|
|
|
Added `get_queryset()` method to `IntegrationViewSet` to manually filter by site:
|
|
|
|
```python
|
|
def get_queryset(self):
|
|
"""
|
|
Override to filter integrations by site.
|
|
SiteIntegration only has 'site' field (no 'sector'), so SiteSectorModelViewSet's
|
|
filtering doesn't apply. We manually filter by site here.
|
|
"""
|
|
queryset = super().get_queryset()
|
|
|
|
# Get site parameter from query params
|
|
site_id = self.request.query_params.get('site_id') or self.request.query_params.get('site')
|
|
|
|
if site_id:
|
|
try:
|
|
site_id_int = int(site_id)
|
|
queryset = queryset.filter(site_id=site_id_int)
|
|
except (ValueError, TypeError):
|
|
# Invalid site_id, return empty queryset
|
|
queryset = queryset.none()
|
|
|
|
return queryset
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Before Fix:
|
|
- Site 5: Showed homeg8.com integration
|
|
- Site 10: Showed homeg8.com integration ❌ (WRONG)
|
|
- Site 14: Showed homeg8.com integration ❌ (WRONG)
|
|
- Site 15: Showed homeg8.com integration ❌ (WRONG)
|
|
|
|
### After Fix:
|
|
- Site 5: Shows its own integration ✅
|
|
- Site 10: Shows its own integration ✅
|
|
- Site 14: Shows its own integration ✅
|
|
- Site 15: Shows its own integration ✅
|
|
|
|
## API Behavior
|
|
|
|
### Before Fix:
|
|
```
|
|
GET /api/v1/integration/integrations/?site=10
|
|
→ Returns ALL integrations for ALL sites
|
|
```
|
|
|
|
### After Fix:
|
|
```
|
|
GET /api/v1/integration/integrations/?site=10
|
|
→ Returns ONLY integrations for site 10
|
|
```
|
|
|
|
## Security Impact
|
|
|
|
This was a **CRITICAL** data isolation bug that could cause:
|
|
- ✅ **Data leakage between sites** (FIXED)
|
|
- ✅ **Wrong content syncing to wrong sites** (FIXED)
|
|
- ✅ **Security/privacy violations** (FIXED)
|
|
|
|
## Deployment
|
|
|
|
1. Fix was applied to: `/data/app/igny8/backend/igny8_core/modules/integration/views.py`
|
|
2. Gunicorn workers were reloaded: `pkill -HUP -f 'gunicorn igny8_core.wsgi'`
|
|
3. Changes are **LIVE** and **WORKING**
|
|
|
|
---
|
|
|
|
**Status**: ✅ **FIXED AND DEPLOYED**
|
|
**Date**: 2025-11-22
|
|
**Critical**: YES
|
|
|