Version: 1.0
Für: packages/bfagent-core
Aufwand: ~5-7 Tage
tenant-rbac/
├── models/
│ ├── __init__.py # Export
│ ├── tenant.py # Tenant Model
│ └── membership.py # TenantMembership Model
├── permissions/
│ ├── __init__.py # Export
│ ├── enums.py # Permission Enum + Role-Mapping
│ ├── checker.py # PermissionChecker (mit Cache)
│ ├── decorators.py # @require_permission, @require_role
│ └── mixins.py # CBV Mixins
├── migrations/
│ ├── 0002_tenant.py # Tenant Migration
│ └── 0003_tenantmembership.py
└── tests/
└── test_tenant_rbac.py # Comprehensive Tests
# In bfagent-core Package
cp -r tenant-rbac/models/* packages/bfagent-core/src/bfagent_core/models/
cp -r tenant-rbac/permissions/* packages/bfagent-core/src/bfagent_core/permissions/
cp tenant-rbac/migrations/* packages/bfagent-core/src/bfagent_core/migrations/
cp tenant-rbac/tests/* packages/bfagent-core/tests/# packages/bfagent-core/src/bfagent_core/__init__.py
from bfagent_core.models import (
Tenant,
TenantStatus,
TenantMembership,
TenantRole,
)
from bfagent_core.permissions import (
Permission,
has_permission,
check_permission,
require_permission,
require_role,
TenantPermissionMixin,
)
__all__ = [
# Models
"Tenant",
"TenantStatus",
"TenantMembership",
"TenantRole",
# Permissions
"Permission",
"has_permission",
"check_permission",
"require_permission",
"require_role",
"TenantPermissionMixin",
# ... etc
]cd apps/your-app
python manage.py migrate bfagent_corefrom bfagent_core.permissions import require_permission, Permission
@require_permission(Permission.STORIES_CREATE)
def create_story(request):
# User hat Permission
...
@require_role("owner", "admin")
def admin_dashboard(request):
# Nur Owner/Admin
...from django.views.generic import ListView, DeleteView
from bfagent_core.permissions import TenantPermissionMixin, Permission
class StoryListView(TenantPermissionMixin, ListView):
required_permission = Permission.STORIES_VIEW
model = Story
class StoryDeleteView(TenantPermissionMixin, DeleteView):
required_role = "admin" # Nur Admin+
model = Storyfrom bfagent_core.permissions import check_permission, Permission
def publish_story(user_id: int, story_id: int) -> Story:
# Wirft PermissionDenied wenn nicht erlaubt
check_permission(user_id, Permission.STORIES_PUBLISH)
story = Story.objects.get(id=story_id)
story.status = "published"
story.save()
return story<!-- Mit Mixin: view.get_user_permissions() -->
{% if 'stories.delete' in view.get_user_permissions %}
<button class="btn-danger">Delete</button>
{% endif %}
{% if 'stories.publish' in view.get_user_permissions %}
<button class="btn-primary">Publish</button>
{% endif %}from rest_framework.generics import ListAPIView
from bfagent_core.permissions import TenantAPIPermissionMixin, Permission
class StoryListAPI(TenantAPIPermissionMixin, ListAPIView):
required_permission = Permission.STORIES_VIEW
serializer_class = StorySerializer| Rolle | Level | Beschreibung |
|---|---|---|
owner |
100 | Vollzugriff, kann Tenant löschen |
admin |
75 | Fast alles, außer Tenant-Delete |
member |
50 | Arbeiten (Create/Edit), kein Delete |
viewer |
25 | Nur Lesen |
| Permission | Owner | Admin | Member | Viewer |
|---|---|---|---|---|
stories.view |
✅ | ✅ | ✅ | ✅ |
stories.create |
✅ | ✅ | ✅ | ❌ |
stories.edit |
✅ | ✅ | ✅ | ❌ |
stories.delete |
✅ | ✅ | ❌ | ❌ |
stories.publish |
✅ | ✅ | ❌ | ❌ |
tenant.delete |
✅ | ❌ | ❌ | ❌ |
ai.premium |
✅ | ✅ | ❌ | ❌ |
# Viewer bekommt zusätzlich CREATE
membership.grant_permission("stories.create")
# Owner verliert DELETE
membership.revoke_permission("stories.delete")
# Zurück zu Role-Default
membership.clear_permission_override("stories.delete")┌─────────┐ activate() ┌─────────┐
│ TRIAL │ ─────────────────▶ │ ACTIVE │
└─────────┘ └─────────┘
│ │
│ soft_delete() │ suspend()
▼ ▼
┌─────────┐ ┌───────────┐
│ DELETED │ ◀──────────────── │ SUSPENDED │
└─────────┘ soft_delete() └───────────┘
│
│ activate()
▼
┌─────────┐
│ ACTIVE │
└─────────┘
# Trial → Active
tenant.activate()
# Suspend (z.B. Zahlung fehlgeschlagen)
tenant.suspend(reason="Payment failed")
# Soft-Delete (Daten bleiben für Compliance)
tenant.soft_delete()cd packages/bfagent-core
pytest tests/test_tenant_rbac.py -v# settings.py
# Tenant-Model für Middleware
TENANT_MODEL = "bfagent_core.Tenant"
TENANT_SLUG_FIELD = "slug"
TENANT_ID_FIELD = "id"
# Base Domain für Subdomains
TENANT_BASE_DOMAIN = "myapp.io" # demo.myapp.io, acme.myapp.io
# Dev-Mode: Admin ohne Tenant erlauben
TENANT_ALLOW_LOCALHOST = DEBUGDer PermissionChecker cached Memberships für 5 Minuten:
from bfagent_core.permissions import invalidate_permission_cache
# Nach Rollen-/Permission-Änderung:
invalidate_permission_cache(tenant_id, user_id)- Dateien kopieren
-
__init__.pyaktualisieren -
python manage.py makemigrations(falls nötig) -
python manage.py migrate - Tests ausführen
- Settings anpassen
- Middleware prüfen
Erstellt für Platform Multi-Tenancy - 2025-01-31