strawberry-graphql 0.229.2.dev1715873118__py3-none-any.whl → 0.229.2.dev1715881453__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
strawberry/permission.py CHANGED
@@ -13,6 +13,7 @@ from typing import (
13
13
  Optional,
14
14
  Tuple,
15
15
  Type,
16
+ TypedDict,
16
17
  Union,
17
18
  )
18
19
  from typing_extensions import deprecated
@@ -37,6 +38,15 @@ if TYPE_CHECKING:
37
38
  from strawberry.types import Info
38
39
 
39
40
 
41
+ def unpack_maybe(
42
+ value: Union[object, Tuple[bool, object]], default: object = None
43
+ ) -> Tuple[object, object]:
44
+ if isinstance(value, tuple) and len(value) == 2:
45
+ return value
46
+ else:
47
+ return value, default
48
+
49
+
40
50
  class BasePermission(abc.ABC):
41
51
  """
42
52
  Base class for creating permissions
@@ -52,7 +62,7 @@ class BasePermission(abc.ABC):
52
62
 
53
63
  @abc.abstractmethod
54
64
  def has_permission(
55
- self, source: Any, info: Info, **kwargs: Any
65
+ self, source: Any, info: Info, **kwargs: object
56
66
  ) -> Union[
57
67
  bool,
58
68
  Awaitable[bool],
@@ -82,7 +92,7 @@ class BasePermission(abc.ABC):
82
92
  "Permission classes should override has_permission method"
83
93
  )
84
94
 
85
- def on_unauthorized(self, **kwargs: Any) -> None:
95
+ def on_unauthorized(self, **kwargs: object) -> None:
86
96
  """
87
97
  Default error raising for permissions.
88
98
  This can be overridden to customize the behavior.
@@ -128,14 +138,18 @@ class BasePermission(abc.ABC):
128
138
  return OrPermission([self, other])
129
139
 
130
140
 
141
+ class CompositePermissionContext(TypedDict):
142
+ failed_permissions: List[Tuple[BasePermission, dict]]
143
+
144
+
131
145
  class CompositePermission(BasePermission, abc.ABC):
132
146
  def __init__(self, child_permissions: List[BasePermission]):
133
147
  self.child_permissions = child_permissions
134
148
 
135
- def on_unauthorized(self, **kwargs: Any) -> Any:
149
+ def on_unauthorized(self, **kwargs: object) -> Any:
136
150
  failed_permissions = kwargs.get("failed_permissions", [])
137
- for permission in failed_permissions:
138
- permission.on_unauthorized()
151
+ for permission, context in failed_permissions:
152
+ permission.on_unauthorized(**context)
139
153
 
140
154
  @cached_property
141
155
  def is_async(self) -> bool:
@@ -144,27 +158,34 @@ class CompositePermission(BasePermission, abc.ABC):
144
158
 
145
159
  class AndPermission(CompositePermission):
146
160
  def has_permission(
147
- self, source: Any, info: Info, **kwargs: Any
161
+ self, source: Any, info: Info, **kwargs: object
148
162
  ) -> Union[
149
163
  bool,
150
164
  Awaitable[bool],
151
- Tuple[Literal[False], dict],
152
- Awaitable[Tuple[Literal[False], dict]],
165
+ Tuple[Literal[False], CompositePermissionContext],
166
+ Awaitable[Tuple[Literal[False], CompositePermissionContext]],
153
167
  ]:
154
168
  if self.is_async:
155
169
  return self._has_permission_async(source, info, **kwargs)
156
170
 
157
171
  for permission in self.child_permissions:
158
- if not permission.has_permission(source, info, **kwargs):
159
- return False, {"failed_permissions": [permission]}
172
+ has_permission, context = unpack_maybe(
173
+ permission.has_permission(source, info, **kwargs), {}
174
+ )
175
+ if not has_permission:
176
+ return False, {"failed_permissions": [(permission, context)]}
160
177
  return True
161
178
 
162
179
  async def _has_permission_async(
163
- self, source: Any, info: Info, **kwargs: Any
164
- ) -> Union[bool, Tuple[Literal[False], dict]]:
180
+ self, source: Any, info: Info, **kwargs: object
181
+ ) -> Union[bool, Tuple[Literal[False], CompositePermissionContext]]:
165
182
  for permission in self.child_permissions:
166
- if not await await_maybe(permission.has_permission(source, info, **kwargs)):
167
- return False, {"failed_permissions": [permission]}
183
+ permission_response = await await_maybe(
184
+ permission.has_permission(source, info, **kwargs)
185
+ )
186
+ has_permission, context = unpack_maybe(permission_response, {})
187
+ if not has_permission:
188
+ return False, {"failed_permissions": [(permission, context)]}
168
189
  return True
169
190
 
170
191
  def __and__(self, other: BasePermission):
@@ -173,7 +194,7 @@ class AndPermission(CompositePermission):
173
194
 
174
195
  class OrPermission(CompositePermission):
175
196
  def has_permission(
176
- self, source: Any, info: Info, **kwargs: Any
197
+ self, source: Any, info: Info, **kwargs: object
177
198
  ) -> Union[
178
199
  bool,
179
200
  Awaitable[bool],
@@ -184,20 +205,27 @@ class OrPermission(CompositePermission):
184
205
  return self._has_permission_async(source, info, **kwargs)
185
206
  failed_permissions = []
186
207
  for permission in self.child_permissions:
187
- if permission.has_permission(source, info, **kwargs):
208
+ has_permission, context = unpack_maybe(
209
+ permission.has_permission(source, info, **kwargs), {}
210
+ )
211
+ if has_permission:
188
212
  return True
189
- failed_permissions.append(permission)
213
+ failed_permissions.append((permission, context))
190
214
 
191
215
  return False, {"failed_permissions": failed_permissions}
192
216
 
193
217
  async def _has_permission_async(
194
- self, source: Any, info: Info, **kwargs: Any
218
+ self, source: Any, info: Info, **kwargs: object
195
219
  ) -> Union[bool, Tuple[Literal[False], dict]]:
196
220
  failed_permissions = []
197
221
  for permission in self.child_permissions:
198
- if await await_maybe(permission.has_permission(source, info, **kwargs)):
222
+ permission_response = await await_maybe(
223
+ permission.has_permission(source, info, **kwargs)
224
+ )
225
+ has_permission, context = unpack_maybe(permission_response, {})
226
+ if has_permission:
199
227
  return True
200
- failed_permissions.append(permission)
228
+ failed_permissions.append((permission, context))
201
229
 
202
230
  return False, {"failed_permissions": failed_permissions}
203
231
 
@@ -253,7 +281,7 @@ class PermissionExtension(FieldExtension):
253
281
  else:
254
282
  raise PermissionFailSilentlyRequiresOptionalError(field)
255
283
 
256
- def _on_unauthorized(self, permission: BasePermission, **kwargs: Any) -> Any:
284
+ def _on_unauthorized(self, permission: BasePermission, **kwargs: object) -> Any:
257
285
  if self.fail_silently:
258
286
  return [] if self.return_empty_list else None
259
287
 
@@ -266,7 +294,7 @@ class PermissionExtension(FieldExtension):
266
294
  next_: SyncExtensionResolver,
267
295
  source: Any,
268
296
  info: Info,
269
- **kwargs: Any[str, Any],
297
+ **kwargs: object[str, Any],
270
298
  ) -> Any:
271
299
  """
272
300
  Checks if the permission should be accepted and
@@ -274,13 +302,9 @@ class PermissionExtension(FieldExtension):
274
302
  """
275
303
 
276
304
  for permission in self.permissions:
277
- permission_response = permission.has_permission(source, info, **kwargs)
278
-
279
- context = {}
280
- if isinstance(permission_response, tuple):
281
- has_permission, context = permission_response
282
- else:
283
- has_permission = permission_response
305
+ has_permission, context = unpack_maybe(
306
+ permission.has_permission(source, info, **kwargs), {}
307
+ )
284
308
 
285
309
  if not has_permission:
286
310
  return self._on_unauthorized(permission, **context)
@@ -292,7 +316,7 @@ class PermissionExtension(FieldExtension):
292
316
  next_: AsyncExtensionResolver,
293
317
  source: Any,
294
318
  info: Info,
295
- **kwargs: Any[str, Any],
319
+ **kwargs: object[str, Any],
296
320
  ) -> Any:
297
321
  for permission in self.permissions:
298
322
  permission_response = await await_maybe(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.229.2.dev1715873118
3
+ Version: 0.229.2.dev1715881453
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -162,7 +162,7 @@ strawberry/litestar/handlers/graphql_ws_handler.py,sha256=vVpjd5rJOldF8aQWEGjmmN
162
162
  strawberry/mutation.py,sha256=NROPvHJU1BBxZB7Wj4Okxw4hDIYM59MCpukAGEmSNYA,255
163
163
  strawberry/object_type.py,sha256=iQL2NqO7I28bS0moWgxPmCDc0w1HewPcXq8Xyh-xAWI,12539
164
164
  strawberry/parent.py,sha256=rmedKjN4zdg4KTnNV8DENrzgNYVL67rXpHjHoBofMS4,825
165
- strawberry/permission.py,sha256=blMwepQb20KLgnpNXWMcMZKa2soRo3zKjKXizPfIrIw,11238
165
+ strawberry/permission.py,sha256=7ePOn4P_n32N_msMnWytzqKZa77HyOQ4u0hp9RliYJo,12098
166
166
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
167
167
  strawberry/printer/ast_from_value.py,sha256=MFIX2V51d9ocRvD0Njemjk8YIzKh2BB1g2iUcX6a3d8,4946
168
168
  strawberry/printer/printer.py,sha256=HUUecFETXWgfQtMzxjx9pNOXP3tDevqlU3sG7TC3AD8,17449
@@ -241,8 +241,8 @@ strawberry/utils/logging.py,sha256=flS7hV0JiIOEdXcrIjda4WyIWix86cpHHFNJL8gl1y4,7
241
241
  strawberry/utils/operation.py,sha256=Um-tBCPl3_bVFN2Ph7o1mnrxfxBes4HFCj6T0x4kZxE,1135
242
242
  strawberry/utils/str_converters.py,sha256=avIgPVLg98vZH9mA2lhzVdyyjqzLsK2NdBw9mJQ02Xk,813
243
243
  strawberry/utils/typing.py,sha256=SQVOw1nuFZk2Pe3iz0o8ebzpoyvBVoGSQZVZj6-8k7I,13483
244
- strawberry_graphql-0.229.2.dev1715873118.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
- strawberry_graphql-0.229.2.dev1715873118.dist-info/METADATA,sha256=MSkHwXiY0s2dglAReE2EXuSKi9WQgZ9c6MI75-KeglE,7835
246
- strawberry_graphql-0.229.2.dev1715873118.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
247
- strawberry_graphql-0.229.2.dev1715873118.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
248
- strawberry_graphql-0.229.2.dev1715873118.dist-info/RECORD,,
244
+ strawberry_graphql-0.229.2.dev1715881453.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
+ strawberry_graphql-0.229.2.dev1715881453.dist-info/METADATA,sha256=alSm87ziLGjzNKwRfESeLKCG_cYypmHsmo7_U3_19_4,7835
246
+ strawberry_graphql-0.229.2.dev1715881453.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
247
+ strawberry_graphql-0.229.2.dev1715881453.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
248
+ strawberry_graphql-0.229.2.dev1715881453.dist-info/RECORD,,