Coverage for postrfp/ref/exceptions.py: 0%
36 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
1"""
2Permission-specific exception classes for the reference content management system.
4These exceptions provide enhanced error reporting with detailed context about
5why permission checks failed and what users can do to resolve access issues.
6"""
8from typing import Any
9from postrfp.shared.exceptions import AuthorizationFailure
12class PermissionDeniedError(AuthorizationFailure):
13 """
14 Enhanced authorization failure with detailed permission context.
16 This exception is designed to work with the existing framework's error
17 handling while providing rich context about permission failures.
18 """
20 def __init__(
21 self,
22 permission_result=None,
23 resource_type: str | None = None,
24 resource_id: Any = None,
25 resource_title: str | None = None,
26 attempted_action: str | None = None,
27 user_org_id: str | None = None,
28 **kwargs,
29 ):
30 self.permission_result = permission_result
31 self.resource_type = resource_type
32 self.resource_id = resource_id
33 self.resource_title = resource_title
34 self.attempted_action = attempted_action
35 self.user_org_id = user_org_id
37 # Build the main error message
38 if permission_result:
39 message = permission_result.get_user_friendly_message()
40 # Set errors for framework compatibility
41 errors = permission_result.to_structured_error()
42 else:
43 message = kwargs.get("message", self.default_message)
44 errors = kwargs.get("errors", None)
46 # Enhance message with resource context if available
47 if resource_title and attempted_action:
48 message = f"Cannot {attempted_action} {resource_type or 'resource'} '{resource_title}': {message}"
50 super().__init__(message=message, errors=errors, **kwargs)
52 def __str__(self) -> str:
53 """Return user-friendly error message."""
54 if self.permission_result:
55 return self.permission_result.get_user_friendly_message()
56 return super().__str__()
59class ContentPermissionDeniedError(PermissionDeniedError):
60 """
61 Specific exception for content permission failures.
63 Provides content-specific error messaging and suggested actions.
64 """
66 def __init__(
67 self,
68 content=None,
69 permission_result=None,
70 attempted_action: str | None = None,
71 user_org_id: str | None = None,
72 **kwargs,
73 ):
74 # Extract content details if content object provided
75 resource_title = content.title if content else kwargs.get("resource_title")
76 resource_id = content.id if content else kwargs.get("resource_id")
78 super().__init__(
79 permission_result=permission_result,
80 resource_type="Content",
81 resource_id=resource_id,
82 resource_title=resource_title,
83 attempted_action=attempted_action,
84 user_org_id=user_org_id,
85 **kwargs,
86 )
89class SubjectPermissionDeniedError(PermissionDeniedError):
90 """
91 Specific exception for subject permission failures.
93 Provides subject-specific error messaging and suggested actions.
94 """
96 def __init__(
97 self,
98 subject=None,
99 permission_result=None,
100 attempted_action: str | None = None,
101 user_org_id: str | None = None,
102 **kwargs,
103 ):
104 # Extract subject details if subject object provided
105 resource_title = subject.name if subject else kwargs.get("resource_title")
106 resource_id = subject.id if subject else kwargs.get("resource_id")
108 super().__init__(
109 permission_result=permission_result,
110 resource_type="Subject",
111 resource_id=resource_id,
112 resource_title=resource_title,
113 attempted_action=attempted_action,
114 user_org_id=user_org_id,
115 **kwargs,
116 )
119def create_content_permission_error(
120 content, permission_result, attempted_action: str, user_org_id: str
121) -> ContentPermissionDeniedError:
122 """
123 Factory function to create content permission errors with proper context.
125 This function generates appropriate suggested actions based on the
126 permission failure reason and content characteristics.
127 """
128 return ContentPermissionDeniedError(
129 content=content,
130 permission_result=permission_result,
131 attempted_action=attempted_action,
132 user_org_id=user_org_id,
133 )
136def create_subject_permission_error(
137 subject, permission_result, attempted_action: str, user_org_id: str
138) -> SubjectPermissionDeniedError:
139 """
140 Factory function to create subject permission errors with proper context.
141 """
142 return SubjectPermissionDeniedError(
143 subject=subject,
144 permission_result=permission_result,
145 attempted_action=attempted_action,
146 user_org_id=user_org_id,
147 )