Task Description
Epic: Epic 1.3: Application Services Layer (#71)
Acceptance Criteria: AuthorizationService interface, Permission checking abstraction, Role-based and resource-based authorization, Context-aware authorization
Implementation Details
Files to Create/Modify
src/forging_blocks/application/services/authorization.py (NEW)
src/forging_blocks/domain/permissions/__init__.py (NEW)
tests/unit/application/services/test_authorization.py (NEW)
AuthorizationService Interface
from abc import ABC, abstractmethod
from typing import TypeVar, Generic, List, Dict, Any, Optional, Protocol
from dataclasses import dataclass
from enum import Enum
TResource = TypeVar('TResource')
TAction = TypeVar('TAction')
class Permission(Enum):
READ = "read"
WRITE = "write"
DELETE = "delete"
ADMIN = "admin"
@dataclass(frozen=True)
class AuthorizationContext:
user_id: str
roles: List[str]
resource_id: Optional[str] = None
resource_type: Optional[str] = None
action: Optional[str] = None
metadata: Dict[str, Any] = None
class AuthorizationService(ABC):
"""Service for authorization and permission checking."""
@abstractmethod
async def check_permission(
self,
context: AuthorizationContext,
permission: Permission
) -> bool:
pass
@abstractmethod
async def check_resource_permission(
self,
context: AuthorizationContext,
resource: TResource,
action: TAction
) -> bool:
pass
@abstractmethod
async def get_user_permissions(self, user_id: str) -> List[Permission]:
pass
@abstractmethod
async def get_user_roles(self, user_id: str) -> List[str]:
pass
class PermissionChecker(Protocol):
"""Protocol for permission checking implementations."""
async def check(self, context: AuthorizationContext, permission: Permission) -> bool:
...
class RoleBasedPermissionChecker(PermissionChecker):
"""Role-based permission checker implementation."""
def __init__(self, role_permissions: Dict[str, List[Permission]]):
self._role_permissions = role_permissions
async def check(self, context: AuthorizationContext, permission: Permission) -> bool:
for role in context.roles:
if role in self._role_permissions:
if permission in self._role_permissions[role]:
return True
return False
Resource-Based Authorization
class ResourcePermissionChecker(PermissionChecker):
"""Resource-based permission checker."""
def __init__(self, resource_policies: Dict[str, List[Permission]]):
self._resource_policies = resource_policies
async def check(self, context: AuthorizationContext, permission: Permission) -> bool:
if not context.resource_type:
return False
resource_type = context.resource_type
if resource_type in self._resource_policies:
return permission in self._resource_policies[resource_type]
return False
class CompositePermissionChecker(PermissionChecker):
"""Combines multiple permission checkers."""
def __init__(self, checkers: List[PermissionChecker]):
self._checkers = checkers
async def check(self, context: AuthorizationContext, permission: Permission) -> bool:
for checker in self._checkers:
if await checker.check(context, permission):
return True
return False
Acceptance Criteria
Definition of Done
Task Description
Epic: Epic 1.3: Application Services Layer (#71)
Acceptance Criteria: AuthorizationService interface, Permission checking abstraction, Role-based and resource-based authorization, Context-aware authorization
Implementation Details
Files to Create/Modify
src/forging_blocks/application/services/authorization.py(NEW)src/forging_blocks/domain/permissions/__init__.py(NEW)tests/unit/application/services/test_authorization.py(NEW)AuthorizationService Interface
Resource-Based Authorization
Acceptance Criteria
Definition of Done