Files
Mitgliederverwaltung/.plans/open/issue-207-authorization-middleware-instanceof-chains.md
T
shahondin1624 b29a268b1d Restructure .plans/ into done/ and open/ subdirectories
- Move completed plan files to .plans/done/
- Move 18 open plan files to .plans/open/
- Update .gitignore to exclude .verified_plans temp file
- Verified all 18 open plans still describe unimplemented issues
2026-04-28 20:30:55 +02:00

74 lines
2.0 KiB
Markdown

# Issue #207: Authorization Middleware Uses instanceof Chains
## Problem
The `AuthorizationMiddleware::getAdminMethods()` method uses a chain of `instanceof` checks to determine admin-only methods:
```php
private function getAdminMethods($controller): ?array {
if ($controller instanceof FeeController) {
return self::ADMIN_METHODS_FEE;
}
if ($controller instanceof StufeController) {
return self::ADMIN_METHODS_STUFE;
}
if ($controller instanceof ExportController) {
return self::ADMIN_METHODS_EXPORT;
}
if ($controller instanceof MemberController) {
return self::ADMIN_METHODS_MEMBER;
}
// ... more controllers
return null;
}
```
This pattern violates Open/Closed Principle — adding a new controller requires modifying the middleware.
## Impact
- Hard to maintain as controller count grows
- Easy to forget to add a new controller to the chain
- Mixing of concerns (controller identity vs. permissions)
## Solution
Use PHP attributes to declare permissions on controller methods:
```php
#[Attribute]
class RequiresAdmin implements \Attribute {}
#[RequiresAdmin]
public function createRule(): JSONResponse { ... }
```
Then scan for attributes in middleware:
```php
public function beforeController($controller, $methodName): void {
$method = new \ReflectionMethod($controller, $methodName);
if ($method->getAttributes(RequiresAdmin::class)) {
if (!$this->permissionService->isAdmin($userId)) {
throw new \RuntimeException('Authorization: admin required');
}
}
// ... rest of checks
}
```
## Tasks
- [ ] Create `RequiresRead` and `RequiresWrite` attributes
- [ ] Create `RequiresAdmin` attribute
- [ ] Add attributes to all controller methods
- [ ] Refactor `AuthorizationMiddleware` to use reflection + attributes
- [ ] Remove `ADMIN_METHODS_*` constants and `getAdminMethods()` method
- [ ] Test all permission levels still work correctly
## Labels
- refactoring
- backend
- priority:medium
- architecture