django bacekdn opeartioanl fixes and site wp integration api fixes

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-11 21:54:08 +00:00
parent 00ef985a5f
commit 3925ddf894
16 changed files with 2045 additions and 89 deletions

View File

@@ -67,25 +67,23 @@ class IntegrationViewSet(SiteSectorModelViewSet):
api_key = serializers.SerializerMethodField()
def get_api_key(self, obj):
"""Return the API key from encrypted credentials"""
credentials = obj.get_credentials()
return credentials.get('api_key', '')
"""Return the API key from Site.wp_api_key (SINGLE source of truth)"""
# API key is stored on Site model, not in SiteIntegration credentials
return obj.site.wp_api_key or ''
def validate(self, data):
"""
Custom validation for WordPress integrations.
API key is the only required authentication method.
API key is stored on Site model, not in SiteIntegration.
"""
validated_data = super().validate(data)
# For WordPress platform, require API key only
# For WordPress platform, check API key exists on Site (not in credentials_json)
if validated_data.get('platform') == 'wordpress':
credentials = validated_data.get('credentials_json', {})
# API key is required for all WordPress integrations
if not credentials.get('api_key'):
site = validated_data.get('site') or getattr(self.instance, 'site', None)
if site and not site.wp_api_key:
raise serializers.ValidationError({
'credentials_json': 'API key is required for WordPress integration.'
'site': 'Site must have an API key generated before creating WordPress integration.'
})
return validated_data
@@ -198,7 +196,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
# Try to find an existing integration for this site+platform
integration = SiteIntegration.objects.filter(site=site, platform='wordpress').first()
# If not found, create and save the integration to database
# If not found, create and save the integration to database (for status tracking, not credentials)
integration_created = False
if not integration:
integration = SiteIntegration.objects.create(
@@ -207,7 +205,7 @@ class IntegrationViewSet(SiteSectorModelViewSet):
platform='wordpress',
platform_type='cms',
config_json={'site_url': site_url} if site_url else {},
credentials_json={'api_key': api_key} if api_key else {},
credentials_json={}, # API key is stored in Site.wp_api_key, not here
is_active=True,
sync_enabled=True
)
@@ -805,27 +803,38 @@ class IntegrationViewSet(SiteSectorModelViewSet):
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
api_key = f"igny8_site_{site_id}_{timestamp}_{random_suffix}"
# Get or create SiteIntegration
# SINGLE SOURCE OF TRUTH: Store API key ONLY in Site.wp_api_key
# This is where APIKeyAuthentication validates against
site.wp_api_key = api_key
site.save(update_fields=['wp_api_key'])
# Get or create SiteIntegration (for integration status/config, NOT credentials)
integration, created = SiteIntegration.objects.get_or_create(
site=site,
platform='wordpress',
defaults={
'integration_type': 'wordpress',
'account': site.account,
'platform': 'wordpress',
'platform_type': 'cms',
'is_active': True,
'credentials_json': {'api_key': api_key},
'sync_enabled': True,
'credentials_json': {}, # Empty - API key is on Site model
'config_json': {}
}
)
# If integration already exists, update the API key
# If integration already exists, just ensure it's active
if not created:
credentials = integration.get_credentials()
credentials['api_key'] = api_key
integration.credentials_json = credentials
integration.is_active = True
integration.sync_enabled = True
# Clear any old credentials_json API key (migrate to Site.wp_api_key)
if integration.credentials_json.get('api_key'):
integration.credentials_json = {}
integration.save()
logger.info(
f"Generated new API key for site {site.name} (ID: {site_id}), "
f"integration {'created' if created else 'updated'}"
f"stored in Site.wp_api_key (single source of truth)"
)
# Serialize the integration with the new key

View File

@@ -122,10 +122,10 @@ def wordpress_status_webhook(request):
request=request
)
# Verify API key matches integration
stored_api_key = integration.credentials_json.get('api_key')
# Verify API key matches Site.wp_api_key (SINGLE source of truth)
stored_api_key = integration.site.wp_api_key
if not stored_api_key or stored_api_key != api_key:
logger.error(f"[wordpress_status_webhook] Invalid API key for integration {integration.id}")
logger.error(f"[wordpress_status_webhook] Invalid API key for site {integration.site.id}")
return error_response(
error='Invalid API key',
status_code=http_status.HTTP_401_UNAUTHORIZED,
@@ -293,8 +293,8 @@ def wordpress_metadata_webhook(request):
request=request
)
# Verify API key
stored_api_key = integration.credentials_json.get('api_key')
# Verify API key against Site.wp_api_key (SINGLE source of truth)
stored_api_key = integration.site.wp_api_key
if not stored_api_key or stored_api_key != api_key:
return error_response(
error='Invalid API key',