(self, request, key)
| 542 | return [] |
| 543 | |
| 544 | def get(self, request, key): |
| 545 | if not network_access_allowed(request, "UI"): |
| 546 | return Response({"success": False, "error": "Network access denied"}, status=status.HTTP_403_FORBIDDEN) |
| 547 | pm = PluginManager.get() |
| 548 | pm.discover_plugins(use_cache=True) |
| 549 | plugins_dir = pm.plugins_dir |
| 550 | logo_path = os.path.join(plugins_dir, key, "logo.png") |
| 551 | lp = pm.get_plugin(key) |
| 552 | if lp and getattr(lp, "path", None): |
| 553 | logo_path = os.path.join(lp.path, "logo.png") |
| 554 | abs_plugins = os.path.abspath(plugins_dir) + os.sep |
| 555 | abs_target = os.path.abspath(logo_path) |
| 556 | if not abs_target.startswith(abs_plugins): |
| 557 | return Response({"success": False, "error": "Invalid plugin path"}, status=status.HTTP_400_BAD_REQUEST) |
| 558 | if not os.path.isfile(logo_path): |
| 559 | return Response({"success": False, "error": "Logo not found"}, status=status.HTTP_404_NOT_FOUND) |
| 560 | return FileResponse(open(logo_path, "rb"), content_type="image/png") |
| 561 | |
| 562 | |
| 563 | class PluginDeleteAPIView(PluginAuthMixin, APIView): |
no test coverage detected