Files
igny8/SYSTEM-AUDIT-REPORT-2025-12-08.md
IGNY8 VPS (Salman) da3b45d1c7 adsasdasd
2025-12-08 11:51:00 +00:00

14 KiB

Complete System Audit Report

Date: December 8, 2025
Scope: Full stack audit - Backend models, permissions, middleware, frontend, documentation
Status: 🔴 CRITICAL ISSUES FOUND


Executive Summary

Overall System State: 🔴 BROKEN

Your multi-tenancy system has 5 CRITICAL ISSUES that are causing widespread failures:

  1. Superuser Access Broken - Session auth blocked on API, no bypass logic working
  2. Permission System Contradictions - Multiple conflicting permission classes
  3. Missing Bypass Logic - Superuser/developer checks removed from critical paths
  4. Account Validation Too Strict - Blocks all users including system accounts
  5. Paid Plan Signup Missing - No path for users to subscribe to paid plans

Impact: Neither regular tenants NOR superusers can access the application.


Critical Issue #1: Superuser Access COMPLETELY BROKEN

Problem

Superusers cannot access the application at all due to conflicting middleware logic.

Root Cause

File: backend/igny8_core/auth/middleware.py:35-41

# Block superuser access via session on non-admin routes (JWT required)
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
if request.user.is_superuser and not auth_header.startswith('Bearer '):
    logout(request)
    return JsonResponse(
        {'success': False, 'error': 'Session authentication not allowed for API. Use JWT.'},
        status=status.HTTP_403_FORBIDDEN,
    )

This blocks ALL superuser access because:

  • Superusers login via Django admin (session-based)
  • Session cookies are sent to API automatically
  • Middleware detects superuser + no JWT = LOGOUT + 403 error
  • Even WITH JWT, there's no bypass logic downstream

Evidence

  1. Middleware forces JWT-only for superusers
  2. No JWT generation on login (traditional Django session auth)
  3. Permission classes have is_superuser checks BUT middleware blocks before reaching them
  4. Admin panel uses session auth, but API rejects it

Impact

  • Superusers cannot access ANY page in the app
  • Developer account cannot debug issues
  • System administration impossible

Critical Issue #2: Permission System Has CONTRADICTIONS

Problem

Three different permission modules with conflicting logic:

Module A: backend/igny8_core/auth/permissions.py

class IsOwnerOrAdmin(permissions.BasePermission):
    def has_permission(self, request, view):
        if getattr(user, "is_superuser", False):
            return True  # ✅ Superuser allowed
        return user.role in ['owner', 'admin', 'developer']

Module B: backend/igny8_core/api/permissions.py

class HasTenantAccess(permissions.BasePermission):
    def has_permission(self, request, view):
        # NO superuser bypass ❌
        # Regular users must have account access
        if account:
            return user_account == account
        return False  # Denies superusers without account match

Module C: backend/igny8_core/admin/base.py

class AccountAdminMixin:
    def get_queryset(self, request):
        if request.user.is_superuser or request.user.is_developer():
            return qs  # ✅ Bypass for superuser/developer

The Contradiction

  • auth/permissions.py - Allows superuser bypass
  • api/permissions.py - NO superuser bypass (strict tenant-only)
  • admin/base.py - Allows superuser/developer bypass
  • ViewSets - Use MIXED permission classes from different modules

Example of Broken ViewSet

File: backend/igny8_core/auth/views.py:144

class UsersViewSet(AccountModelViewSet):
    permission_classes = [
        IsAuthenticatedAndActive,  # From api/permissions - no bypass
        HasTenantAccess,           # From api/permissions - no bypass
        IsOwnerOrAdmin             # From auth/permissions - has bypass
    ]

Result: Permission denied because HasTenantAccess (2nd check) fails before IsOwnerOrAdmin (3rd check) runs.

Impact

  • Inconsistent behavior across endpoints
  • Some endpoints work, some don't
  • Debugging is impossible - which permission is denying?

Critical Issue #3: Account Validation TOO STRICT

Problem

Middleware validation blocks even system accounts and developers.

File: backend/igny8_core/auth/middleware.py:148-170 + auth/utils.py:133-195

def _validate_account_and_plan(self, request, user):
    from .utils import validate_account_and_plan
    is_valid, error_message, http_status = validate_account_and_plan(user)
    if not is_valid:
        return self._deny_request(request, error_message, http_status)
def validate_account_and_plan(user_or_account):
    account = getattr(user_or_account, 'account', None)
    if not account:
        return (False, 'Account not configured', 403)
    
    if account.status in ['suspended', 'cancelled']:
        return (False, f'Account is {account.status}', 403)
    
    plan = getattr(account, 'plan', None)
    if not plan:
        return (False, 'No subscription plan', 402)
    
    if not plan.is_active:
        return (False, 'Active subscription required', 402)
    
    return (True, None, None)

The Problem

NO bypass for:

  • Superusers (is_superuser=True)
  • Developer role (role='developer')
  • System accounts (aws-admin, default-account)

Even the developer account (dev@igny8.com) gets blocked if:

  • Their account doesn't have a plan
  • Their plan is inactive
  • Their account status is suspended

Impact

  • Cannot fix issues even with superuser access
  • System accounts get blocked
  • No emergency access path

Critical Issue #4: Missing Bypass Logic in Core Components

AccountModelViewSet - NO Bypass

File: backend/igny8_core/api/base.py:17-42

def get_queryset(self):
    queryset = super().get_queryset()
    if hasattr(queryset.model, 'account'):
        # Filter by account
        if account:
            queryset = queryset.filter(account=account)
        else:
            return queryset.none()  # ❌ Blocks everyone without account

Missing:

  • No check for is_superuser
  • No check for role='developer'
  • No check for system accounts

HasTenantAccess Permission - NO Bypass

File: backend/igny8_core/api/permissions.py:23-52

class HasTenantAccess(permissions.BasePermission):
    def has_permission(self, request, view):
        # NO superuser bypass
        if account:
            return user_account == account
        return False  # ❌ Denies superusers

Impact

Every API endpoint using these base classes is broken for superusers.


Critical Issue #5: Paid Plan Signup Path MISSING

Problem

Marketing page shows paid plans ($89, $139, $229) but all signup buttons go to free trial.

File: tenancy-accounts-payments-still-have issues/PRICING-TO-PAID-SIGNUP-GAP.md

Gap Analysis

  • Free trial signup works
  • Paid plan signup does NOT exist
  • No payment page
  • No plan selection on signup
  • No payment method collection

Missing Components

  1. Payment page UI (frontend)
  2. Plan parameter routing (/signup?plan=starter)
  3. Payment method selection
  4. Pending payment account creation
  5. Bank transfer confirmation flow

Models & Database State

What's Working

  1. Models are well-designed:

    • Account, User, Plan, Subscription, Site, Sector
    • Credit system (CreditTransaction, CreditUsageLog)
    • Payment/Invoice models exist
    • Proper relationships (ForeignKey, OneToOne)
  2. Database has data:

    • 5 plans (free, starter, growth, scale, enterprise)
    • 8 accounts actively using system
    • 280+ credit transactions
    • Credit tracking working
  3. Soft delete implemented:

    • SoftDeletableModel base class
    • Retention policies
    • Restore functionality

What's Broken

  1. Missing field in Account model:

    • payment_method field defined in model but NOT in database (migration missing)
  2. Subscription table empty:

    • No subscriptions exist despite Subscription model
    • Users operating on credits without subscription tracking
  3. Payment system incomplete:

    • Models exist but no data
    • No payment gateway integration
    • No invoice generation in use

Documentation Issues

Problem: Scattered & Contradictory

Three separate doc folders:

  1. master-docs/ - Structured, organized, but may be outdated
  2. old-docs/ - Legacy docs, unclear what's still valid
  3. tenancy-accounts-payments-still-have issues/ - Recent fixes, most accurate

Contradictions Found

  1. Superuser bypass: Docs say it exists, code shows it was removed
  2. Payment methods: Docs describe manual payment flow, but frontend doesn't implement it
  3. Plan allocation: Docs show complex fallback logic, implementation shows it was simplified
  4. Session auth: Docs don't mention JWT requirement for API

Missing from Docs

  1. Current state of superuser access (broken)
  2. Which permission module is canonical
  3. Middleware validation rules
  4. Account.payment_method migration status

Frontend Analysis

Frontend Code Quality: GOOD

  • Well-structured React/TypeScript
  • Proper state management (Zustand)
  • Error handling hooks exist
  • API service layer organized

Frontend Issues

  1. No paid plan signup page - Missing /payment route
  2. No error display for permission denied - Silent failures
  3. No JWT token generation - Still using session auth
  4. No superuser indicator - Users don't know why access is denied

ROOT CAUSE ANALYSIS

Timeline of What Happened

  1. Initially: Superuser had full bypass, everything worked
  2. Tenancy work started: Added strict tenant isolation
  3. Security concern: Removed some bypass logic to prevent session contamination
  4. Over-correction: Removed TOO MUCH bypass logic
  5. Now: Neither tenants nor superusers can access anything

The Core Problem

Attempted to fix security issue but broke fundamental access:

  • Session contamination IS a real issue
  • JWT-only for API IS correct approach
  • BUT: Removed all bypass logic instead of fixing authentication method
  • AND: Middleware blocks before permission classes can allow bypass

RECOMMENDATIONS

I have TWO OPTIONS for you:

Option 1: QUICK FIX (2-4 hours)

Restore superuser access immediately, patch critical flows

Pros:

  • Fastest path to working system
  • Superuser can access app today
  • Tenant system keeps working

Cons:

  • Technical debt remains
  • Documentation still messy
  • Some inconsistencies persist

What gets fixed:

  1. Add superuser bypass to middleware
  2. Add developer role bypass to HasTenantAccess
  3. Add system account bypass to AccountModelViewSet
  4. Generate JWT tokens on login
  5. Update frontend to use JWT

Estimated time: 2-4 hours
Effort: LOW
Risk: LOW


Option 2: PROPER REBUILD (2-3 days) 🏗️

Redesign tenancy system with clean architecture

Pros:

  • Clean, maintainable code
  • Consistent permission logic
  • Proper documentation
  • All flows working correctly
  • Future-proof architecture

Cons:

  • Takes 2-3 days
  • Requires careful testing
  • Must migrate existing data

What gets rebuilt:

  1. Unified permission system - One module, clear hierarchy
  2. Clean middleware - Proper bypass logic for all roles
  3. JWT authentication - Token generation + refresh
  4. Paid plan signup - Complete payment flow
  5. Consolidated docs - Single source of truth
  6. Account migration - Add missing payment_method field
  7. Subscription system - Link accounts to subscriptions
  8. Test suite - Cover all permission scenarios

Estimated time: 2-3 days
Effort: MEDIUM
Risk: MEDIUM (with proper testing)


MY RECOMMENDATION

Start with Option 1 (Quick Fix), then Option 2

Why:

  1. You need access NOW - can't wait 3 days
  2. Quick fix restores functionality in hours
  3. Then properly rebuild when system is accessible
  4. Less risk - incremental improvement

Action Plan:

  1. NOW: Quick fix (2-4 hours) - restore superuser access
  2. Tomorrow: Test all flows, document issues
  3. Next 2-3 days: Proper rebuild with clean architecture
  4. End result: Production-ready multi-tenancy system

Next Steps

Please confirm which option you want:

Option A: Quick fix now (I'll start immediately)
Option B: Full rebuild (2-3 days, but cleaner)
Option C: Quick fix now + full rebuild after (RECOMMENDED)

Once you confirm, I'll begin implementation with detailed progress updates.


File Inventory (Issues Found)

Backend Files with Issues

  1. /backend/igny8_core/auth/middleware.py - Blocks superusers
  2. /backend/igny8_core/auth/utils.py - No bypass in validation
  3. /backend/igny8_core/api/permissions.py - No superuser bypass
  4. /backend/igny8_core/api/base.py - No bypass in queryset filter
  5. ⚠️ /backend/igny8_core/auth/models.py - Missing payment_method migration
  6. /backend/igny8_core/auth/views.py - Mixed permission classes

Frontend Files with Issues

  1. ⚠️ /frontend/src/services/api.ts - No JWT token handling
  2. /frontend/src/pages/Payment.tsx - MISSING (paid signup)
  3. ⚠️ /frontend/src/components/auth/SignUpForm.tsx - No plan parameter

Documentation Issues

  1. ⚠️ master-docs/ - May be outdated
  2. ⚠️ old-docs/ - Unclear what's valid
  3. tenancy-accounts-payments-still-have issues/ - Most accurate

Legend:

  • = Critical issue, must fix
  • ⚠️ = Important but not blocking
  • = Missing component

Conclusion

Your system has good architecture but broken implementation due to over-correction during security fixes. The models are solid, the database is working, but the permission/access layer is preventing anyone (including you) from using the app.

The good news: This is fixable in a few hours with targeted changes.

Waiting for your decision on which option to proceed with...