|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
15 | 15 | import base64
|
| 16 | +import json |
16 | 17 | from typing import Dict, List, Optional
|
17 | 18 |
|
18 | 19 | import aiohttp
|
@@ -263,73 +264,114 @@ def parse_jwt_token(self, token: str, **kwargs) -> Dict:
|
263 | 264 |
|
264 | 265 | async def enforce(
|
265 | 266 | self,
|
266 |
| - permission_model_name: str, |
267 |
| - sub: str, |
268 |
| - obj: str, |
269 |
| - act: str, |
270 |
| - v3: Optional[str] = None, |
271 |
| - v4: Optional[str] = None, |
272 |
| - v5: Optional[str] = None, |
| 267 | + permission_id: str, |
| 268 | + model_id: str, |
| 269 | + resource_id: str, |
| 270 | + enforce_id: str, |
| 271 | + owner: str, |
| 272 | + casbin_request: Optional[List[str]] = None, |
273 | 273 | ) -> bool:
|
274 | 274 | """
|
275 |
| - Send data to Casdoor enforce API |
276 |
| - # https://casdoor.org/docs/permission/exposed-casbin-apis#enforce |
277 |
| -
|
278 |
| - :param permission_model_name: Name permission model |
279 |
| - :param sub: sub from Casbin |
280 |
| - :param obj: obj from Casbin |
281 |
| - :param act: act from Casbin |
282 |
| - :param v3: v3 from Casbin |
283 |
| - :param v4: v4 from Casbin |
284 |
| - :param v5: v5 from Casbin |
| 275 | + Send data to Casdoor enforce API asynchronously |
| 276 | +
|
| 277 | + :param permission_id: the permission id (i.e. organization name/permission name) |
| 278 | + :param model_id: the model id |
| 279 | + :param resource_id: the resource id |
| 280 | + :param enforce_id: the enforce id |
| 281 | + :param owner: the owner of the permission |
| 282 | + :param casbin_request: a list containing the request data (i.e. sub, obj, act) |
| 283 | + :return: a boolean value indicating whether the request is allowed |
285 | 284 | """
|
286 |
| - path = "/api/enforce" |
287 |
| - params = { |
288 |
| - "id": permission_model_name, |
289 |
| - "v0": sub, |
290 |
| - "v1": obj, |
291 |
| - "v2": act, |
292 |
| - "v3": v3, |
293 |
| - "v4": v4, |
294 |
| - "v5": v5, |
| 285 | + url = "/api/enforce" |
| 286 | + params: Dict[str, str] = { |
| 287 | + "permissionId": permission_id, |
| 288 | + "modelId": model_id, |
| 289 | + "resourceId": resource_id, |
| 290 | + "enforceId": enforce_id, |
| 291 | + "owner": owner, |
295 | 292 | }
|
| 293 | + |
296 | 294 | async with self._session as session:
|
297 |
| - has_permission = await session.post(path, headers=self.headers, json=params) |
298 |
| - if not isinstance(has_permission, bool): |
299 |
| - raise ValueError(f"Casdoor response error: {has_permission}") |
300 |
| - return has_permission |
| 295 | + response = await session.post( |
| 296 | + url, |
| 297 | + params=params, |
| 298 | + data=json.dumps(casbin_request), |
| 299 | + auth=aiohttp.BasicAuth(self.client_id, self.client_secret), |
| 300 | + headers={"Content-Type": "application/json"}, |
| 301 | + ) |
| 302 | + |
| 303 | + if isinstance(response, dict): |
| 304 | + data = response.get("data") |
| 305 | + if isinstance(data, list) and len(data) > 0: |
| 306 | + has_permission = data[0] |
| 307 | + else: |
| 308 | + has_permission = response |
| 309 | + else: |
| 310 | + has_permission = response |
301 | 311 |
|
302 |
| - async def batch_enforce(self, permission_model_name: str, permission_rules: List[List[str]]) -> List[bool]: |
303 |
| - """ |
304 |
| - Send data to Casdoor enforce API |
305 |
| -
|
306 |
| - :param permission_model_name: Name permission model |
307 |
| - :param permission_rules: permission rules to enforce |
308 |
| - [][0] -> sub: sub from Casbin |
309 |
| - [][1] -> obj: obj from Casbin |
310 |
| - [][2] -> act: act from Casbin |
311 |
| - [][3] -> v3: v3 from Casbin (optional) |
312 |
| - [][4] -> v4: v4 from Casbin (optional) |
313 |
| - [][5] -> v5: v5 from Casbin (optional) |
314 |
| - """ |
315 |
| - path = "/api/batch-enforce" |
| 312 | + if not isinstance(has_permission, bool): |
| 313 | + error_str = f"Casdoor response error (invalid type {type(has_permission)}):\n{json.dumps(response)}" |
| 314 | + raise ValueError(error_str) |
316 | 315 |
|
317 |
| - def map_rule(rule: List[str], idx) -> Dict: |
318 |
| - if len(rule) < 3: |
319 |
| - raise ValueError(f"Invalid permission rule[{idx}]: {rule}") |
320 |
| - result = {"id": permission_model_name} |
321 |
| - for i in range(len(rule)): |
322 |
| - result.update({f"v{i}": rule[i]}) |
323 |
| - return result |
| 316 | + return has_permission |
324 | 317 |
|
325 |
| - params = [map_rule(permission_rules[i], i) for i in range(len(permission_rules))] |
| 318 | + async def batch_enforce( |
| 319 | + self, |
| 320 | + permission_id: str, |
| 321 | + model_id: str, |
| 322 | + enforce_id: str, |
| 323 | + owner: str, |
| 324 | + casbin_request: Optional[List[List[str]]] = None, |
| 325 | + ) -> List[bool]: |
| 326 | + """ |
| 327 | + Send data to Casdoor batch enforce API asynchronously |
| 328 | +
|
| 329 | + :param permission_id: the permission id (i.e. organization name/permission name) |
| 330 | + :param model_id: the model id |
| 331 | + :param enforce_id: the enforce id |
| 332 | + :param owner: the owner of the permission |
| 333 | + :param casbin_request: a list of lists containing the request data |
| 334 | + :return: a list of boolean values indicating whether each request is allowed |
| 335 | + """ |
| 336 | + url = "/api/batch-enforce" |
| 337 | + params = { |
| 338 | + "permissionId": permission_id, |
| 339 | + "modelId": model_id, |
| 340 | + "enforceId": enforce_id, |
| 341 | + "owner": owner, |
| 342 | + } |
326 | 343 |
|
327 | 344 | async with self._session as session:
|
328 |
| - enforce_results = await session.post(path, headers=self.headers, json=params) |
329 |
| - if not isinstance(enforce_results, bool): |
330 |
| - raise ValueError(f"Casdoor response error:{enforce_results}") |
331 |
| - |
332 |
| - return enforce_results |
| 345 | + response = await session.post( |
| 346 | + url, |
| 347 | + params=params, |
| 348 | + data=json.dumps(casbin_request), |
| 349 | + auth=aiohttp.BasicAuth(self.client_id, self.client_secret), |
| 350 | + headers={"Content-Type": "application/json"}, |
| 351 | + ) |
| 352 | + |
| 353 | + data = response.get("data") |
| 354 | + if data is None: |
| 355 | + error_str = "Casdoor response error: 'data' field is missing\n" + json.dumps(response) |
| 356 | + raise ValueError(error_str) |
| 357 | + |
| 358 | + if not isinstance(data, list): |
| 359 | + error_str = f"Casdoor 'data' is not a list (got {type(data)}):\n{json.dumps(response)}" |
| 360 | + raise ValueError(error_str) |
| 361 | + |
| 362 | + enforce_results = data[0] if data else [] |
| 363 | + |
| 364 | + if ( |
| 365 | + not isinstance(enforce_results, list) |
| 366 | + or len(enforce_results) > 0 |
| 367 | + and not isinstance(enforce_results[0], bool) |
| 368 | + ): |
| 369 | + error_str = ( |
| 370 | + f"Casdoor response contains invalid results (got {type(enforce_results)}):\n{json.dumps(response)}" |
| 371 | + ) |
| 372 | + raise ValueError(error_str) |
| 373 | + |
| 374 | + return enforce_results |
333 | 375 |
|
334 | 376 | async def get_users(self) -> Dict:
|
335 | 377 | """
|
|
0 commit comments