18 KiB
Implementation Plan - Remaining API Standard v1.0 Items
Date: 2025-01-XX
Status: Planning
Purpose: Complete implementation plan for remaining API Standard v1.0 compliance items
Executive Summary
Total Items: 10 remaining items
Critical Priority: 2 items
High Priority: 4 items
Medium Priority: 4 items
Estimated Time: 12-16 hours
Risk Level: Low (mostly adding permissions and refactoring response formats)
Table of Contents
- Critical Priority Items
- High Priority Items
- Medium Priority Items
- Implementation Order
- Testing Strategy
- Rollback Plan
Critical Priority Items
1. Fix Auth Endpoints to Use Unified Format
Issue: RegisterView, LoginView, ChangePasswordView, MeView in backend/igny8_core/auth/urls.py use raw Response() instead of unified format helpers.
Impact: These are the most frequently used endpoints and don't comply with the standard.
Files to Modify:
backend/igny8_core/auth/urls.py
Implementation Steps:
-
Update RegisterView (lines 41-58)
# BEFORE: return Response({ 'success': True, 'message': 'Registration successful', 'user': user_serializer.data }, status=status.HTTP_201_CREATED) # AFTER: from igny8_core.api.response import success_response, error_response return success_response( data={'user': user_serializer.data}, message='Registration successful', status_code=status.HTTP_201_CREATED, request=request ) -
Update LoginView (lines 66-134)
- Replace all
Response()calls withsuccess_response()orerror_response() - Ensure
request_idis included - Fix error response format to use
error+errorsstructure
- Replace all
-
Update ChangePasswordView (lines 142-167)
- Replace
Response()withsuccess_response()anderror_response() - Ensure proper error format
- Replace
-
Update MeView (lines 175-188)
- Replace
Response()withsuccess_response() - Ensure
request_idis included
- Replace
-
Add imports at top of file:
from igny8_core.api.response import success_response, error_response
Testing:
- Test registration with valid/invalid data
- Test login with valid/invalid credentials
- Test change password with valid/invalid old password
- Test /me endpoint
- Verify all responses have
success,data/error,request_idfields
Estimated Time: 2 hours
2. Fix AIPromptViewSet Permissions
Issue: AIPromptViewSet has permission_classes = [] which allows unauthenticated access.
Impact: Security vulnerability - anyone can access/modify AI prompts.
Files to Modify:
backend/igny8_core/modules/system/views.py(line 42)
Implementation Steps:
-
Update permission_classes:
# BEFORE: permission_classes = [] # Allow any for now (backward compatibility) # AFTER: from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] -
Verify custom actions have proper permissions:
get_by_type- Should allow authenticated userssave_prompt- Should requireIsEditorOrAbove(per standard: "Saving prompts requires editor/admin")reset_prompt- Should requireIsEditorOrAbove
-
Update save_prompt action:
@action(detail=False, methods=['post'], url_path='save', url_name='save') def save_prompt(self, request): """Save or update a prompt - requires editor or above""" # Add permission check from igny8_core.api.permissions import IsEditorOrAbove if not IsEditorOrAbove().has_permission(request, self): return error_response( error='Permission denied', status_code=status.HTTP_403_FORBIDDEN, request=request ) # ... rest of implementation
Testing:
- Test unauthenticated access (should return 401)
- Test authenticated user access (should work)
- Test save_prompt with viewer role (should return 403)
- Test save_prompt with editor role (should work)
Estimated Time: 1 hour
High Priority Items
3. Update Billing ViewSets to Use Standard Permissions
Issue: All billing ViewSets use permissions.IsAuthenticated instead of IsAuthenticatedAndActive + HasTenantAccess.
Files to Modify:
backend/igny8_core/modules/billing/views.py
Implementation Steps:
-
Update CreditBalanceViewSet (line 35)
# BEFORE: permission_classes = [permissions.IsAuthenticated] # AFTER: from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] -
Update CreditUsageViewSet (line 91)
# BEFORE: permission_classes = [permissions.IsAuthenticated] # AFTER: permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] -
Update CreditTransactionViewSet (line 466)
# BEFORE: permission_classes = [permissions.IsAuthenticated] # AFTER: from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner]Note: Transactions require admin/owner per standard.
Testing:
- Test with unauthenticated user (should return 401)
- Test with authenticated user from different account (should return 403)
- Test with authenticated user from same account (should work)
- Test CreditTransactionViewSet with viewer/editor (should return 403)
- Test CreditTransactionViewSet with admin/owner (should work)
Estimated Time: 1.5 hours
4. Update System Settings ViewSets to Use Standard Permissions
Issue: All 5 system settings ViewSets use permissions.IsAuthenticated instead of standard permissions.
Files to Modify:
backend/igny8_core/modules/system/settings_views.py
Implementation Steps:
-
Update SystemSettingsViewSet (line 37)
# BEFORE: permission_classes = [permissions.IsAuthenticated] # AFTER: from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] # Update get_permissions() method to use IsAdminOrOwner for write operations def get_permissions(self): if self.action in ['create', 'update', 'partial_update', 'destroy']: return [IsAdminOrOwner()] return [IsAuthenticatedAndActive(), HasTenantAccess()] -
Update AccountSettingsViewSet (line 88)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] # Write operations should require IsAdminOrOwner (already handled by get_permissions) -
Update UserSettingsViewSet (line 148)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] -
Update ModuleSettingsViewSet (line 214)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess] -
Update AISettingsViewSet (line 293)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess]
Testing:
- Test read operations with authenticated user (should work)
- Test write operations with viewer/editor (should return 403)
- Test write operations with admin/owner (should work)
- Test with user from different account (should return 403)
Estimated Time: 2 hours
Medium Priority Items
5. Refactor Billing ViewSets to Use AccountModelViewSet
Issue: Billing ViewSets manually filter by account instead of using base class.
Files to Modify:
backend/igny8_core/modules/billing/views.py
Implementation Steps:
-
Refactor CreditBalanceViewSet:
- Change from
viewsets.ViewSetto inherit from a base class - Since it's a custom action-only ViewSet, keep as ViewSet but ensure account filtering
- Verify account is set correctly from request
- Change from
-
Refactor CreditUsageViewSet:
# BEFORE: class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet): def get_queryset(self): account = getattr(self.request, 'account', None) # ... manual filtering # AFTER: from igny8_core.api.base import AccountModelViewSet class CreditUsageViewSet(AccountModelViewSet): # Base class handles account filtering automatically def get_queryset(self): queryset = super().get_queryset() # Only add custom filtering here (operation_type, date range) # Account filtering is automatic -
Refactor CreditTransactionViewSet:
# BEFORE: class CreditTransactionViewSet(viewsets.ReadOnlyModelViewSet): def get_queryset(self): account = getattr(self.request, 'account', None) # ... manual filtering # AFTER: class CreditTransactionViewSet(AccountModelViewSet): # Base class handles account filtering automatically
Testing:
- Verify account filtering works correctly
- Test with admin/developer (should see all accounts)
- Test with regular user (should only see their account)
- Verify custom filters still work (operation_type, date range)
Estimated Time: 2 hours
6. Refactor IntegrationSettingsViewSet to Use AccountModelViewSet
Issue: IntegrationSettingsViewSet inherits from viewsets.ViewSet instead of AccountModelViewSet.
Files to Modify:
backend/igny8_core/modules/system/integration_views.py
Implementation Steps:
-
Change base class:
# BEFORE: class IntegrationSettingsViewSet(viewsets.ViewSet): # AFTER: from igny8_core.api.base import AccountModelViewSet class IntegrationSettingsViewSet(AccountModelViewSet): -
Update methods to use base class features:
get_queryset()- Use base class method if model has account fieldperform_create()- Use base class to set account- Verify account scoping works correctly
-
Note: This ViewSet uses custom URL patterns, so ensure base class doesn't conflict.
Testing:
- Test integration settings retrieval (should be account-scoped)
- Test saving integration settings (should set account automatically)
- Test with user from different account (should not see other account's settings)
Estimated Time: 1.5 hours
7. Add Explicit Standard Permissions to Auth ViewSets
Issue: Auth ViewSets inherit from AccountModelViewSet but don't explicitly set standard permissions.
Files to Modify:
backend/igny8_core/auth/views.py
Implementation Steps:
-
Update UsersViewSet (line 135)
from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner] -
Update AccountsViewSet (line 270)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner] -
Update SubscriptionsViewSet (line 335)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner] -
Update SiteViewSet (line 472)
from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsEditorOrAbove permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsEditorOrAbove] -
Update SectorViewSet (line 715)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsEditorOrAbove] -
Update SiteUserAccessViewSet (line 396)
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner]
Testing:
- Test each ViewSet with appropriate roles
- Verify tenant isolation works
- Test with users from different accounts
Estimated Time: 1.5 hours
8. Add Role-Based Permissions to CreditTransactionViewSet
Issue: CreditTransactionViewSet should require IsAdminOrOwner per standard but currently only requires IsAuthenticated.
Files to Modify:
backend/igny8_core/modules/billing/views.py(line 466)
Implementation Steps:
-
Update permissions:
# This is already covered in item #3, but ensure it's implemented: from igny8_core.api.permissions import IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner] -
Verify in standard: Per API Standard v1.0, billing/transactions require admin/owner.
Testing:
- Test with viewer role (should return 403)
- Test with editor role (should return 403)
- Test with admin role (should work)
- Test with owner role (should work)
Estimated Time: 0.5 hours (included in item #3)
Implementation Order
Phase 1: Critical Security Fixes (3 hours)
- ✅ Fix AIPromptViewSet permissions (1 hour) - CRITICAL SECURITY
- ✅ Fix auth endpoints unified format (2 hours) - HIGH VISIBILITY
Phase 2: High Priority Permissions (3.5 hours)
- ✅ Update billing ViewSets permissions (1.5 hours)
- ✅ Update system settings ViewSets permissions (2 hours)
Phase 3: Base Class Refactoring (3.5 hours)
- ✅ Refactor billing ViewSets to use AccountModelViewSet (2 hours)
- ✅ Refactor IntegrationSettingsViewSet (1.5 hours)
Phase 4: Auth Module Permissions (1.5 hours)
- ✅ Add explicit permissions to auth ViewSets (1.5 hours)
Total Estimated Time: 11.5 hours
Testing Strategy
Unit Tests
File: backend/igny8_core/api/tests/test_auth_endpoints.py (NEW)
class AuthEndpointsTestCase(TestCase):
def test_register_returns_unified_format(self):
"""Test register endpoint returns unified format"""
response = self.client.post('/api/v1/auth/register/', {
'email': 'test@example.com',
'password': 'testpass123',
'password_confirm': 'testpass123'
})
data = response.json()
self.assertIn('success', data)
self.assertTrue(data['success'])
self.assertIn('data', data)
self.assertIn('request_id', data)
def test_login_returns_unified_format(self):
"""Test login endpoint returns unified format"""
# ... test implementation
def test_change_password_returns_unified_format(self):
"""Test change password endpoint returns unified format"""
# ... test implementation
def test_me_returns_unified_format(self):
"""Test /me endpoint returns unified format"""
# ... test implementation
File: backend/igny8_core/api/tests/test_permissions_billing.py (NEW)
class BillingPermissionsTestCase(TestCase):
def test_credit_balance_requires_authentication(self):
"""Test credit balance requires authentication"""
# ... test implementation
def test_credit_transactions_requires_admin(self):
"""Test credit transactions requires admin/owner"""
# ... test implementation
Integration Tests
Update: backend/igny8_core/api/tests/test_integration_auth.py
- Add tests for auth endpoints unified format
- Test permission enforcement
Update: backend/igny8_core/api/tests/test_integration_billing.py
- Add tests for permission enforcement
- Test account scoping
Update: backend/igny8_core/api/tests/test_integration_system.py
- Add tests for AIPromptViewSet permissions
- Test system settings permissions
Manual Testing Checklist
- Test registration with valid/invalid data
- Test login with valid/invalid credentials
- Test change password
- Test /me endpoint
- Test AIPromptViewSet with unauthenticated user (should fail)
- Test AIPromptViewSet save_prompt with viewer (should fail)
- Test billing endpoints with different roles
- Test system settings with different roles
- Test account isolation on all endpoints
- Verify all responses have unified format
Rollback Plan
If Issues Arise:
-
Immediate Rollback:
- Revert git commits for problematic changes
- Restore previous version
- Monitor for issues
-
Partial Rollback:
- Revert specific module changes
- Keep other improvements
- Fix issues incrementally
-
Feature Flag:
- Add feature flag for new permissions
- Disable if issues found
- Re-enable after fixes
Rollback Order (if needed):
- Auth endpoints (most visible)
- Permissions (security critical)
- Base class refactoring (less visible)
Success Criteria
Definition of Done
- All auth endpoints return unified format
- All ViewSets use standard permissions
- All ViewSets use base classes where applicable
- All tests pass
- Manual testing completed
- No security vulnerabilities
- CHANGELOG updated with accurate information
Metrics
- Coverage: 100% of remaining items implemented
- Test Coverage: >90% for modified code
- Security: No endpoints allow unauthenticated access (except public endpoints)
- Compliance: 100% compliance with API Standard v1.0
Notes
- All changes should maintain backward compatibility where possible
- Permission changes may require frontend updates if error handling changes
- Test thoroughly before deploying to production
- Update CHANGELOG.md after completion to reflect accurate status
Document Status: Implementation Plan
Last Updated: 2025-01-XX
Next Steps: Begin Phase 1 implementation