(self, request)
| 873 | })}, |
| 874 | ) |
| 875 | def post(self, request): |
| 876 | url = (request.data.get("url") or "").strip() |
| 877 | public_key = (request.data.get("public_key") or "").strip() |
| 878 | if not url: |
| 879 | return Response( |
| 880 | {"error": "url is required"}, |
| 881 | status=status.HTTP_400_BAD_REQUEST, |
| 882 | ) |
| 883 | try: |
| 884 | key_text = public_key or None |
| 885 | data, verified = _fetch_manifest(url, public_key_text=key_text) |
| 886 | manifest_inner = data.get("manifest", data) |
| 887 | registry_name = (manifest_inner.get("registry_name") or "").strip() |
| 888 | registry_url = (manifest_inner.get("registry_url") or "").strip() |
| 889 | plugin_count = len(manifest_inner.get("plugins", [])) |
| 890 | errors = [] |
| 891 | if not registry_name: |
| 892 | errors.append("Manifest is missing a 'registry_name'.") |
| 893 | elif _is_official_sounding(registry_name): |
| 894 | errors.append(f"The registry name '{registry_name}' is not allowed because it may be confused with an official repo.") |
| 895 | if PluginRepo.objects.filter(url=url).exists(): |
| 896 | errors.append("This manifest URL has already been added.") |
| 897 | return Response({ |
| 898 | "valid": len(errors) == 0, |
| 899 | "registry_name": registry_name, |
| 900 | "registry_url": registry_url, |
| 901 | "signature_verified": verified, |
| 902 | "plugin_count": plugin_count, |
| 903 | "errors": errors, |
| 904 | }) |
| 905 | except http_requests.exceptions.Timeout: |
| 906 | return Response( |
| 907 | {"valid": False, "errors": ["The request timed out. Check the URL and try again."]}, |
| 908 | status=status.HTTP_200_OK, |
| 909 | ) |
| 910 | except http_requests.exceptions.ConnectionError: |
| 911 | return Response( |
| 912 | {"valid": False, "errors": ["Could not connect to the server. Check the URL and your network connection."]}, |
| 913 | status=status.HTTP_200_OK, |
| 914 | ) |
| 915 | except http_requests.exceptions.HTTPError as e: |
| 916 | code = e.response.status_code if e.response is not None else None |
| 917 | if code == 404: |
| 918 | msg = "Manifest not found (404). Check that the URL points to a valid manifest file." |
| 919 | elif code == 403: |
| 920 | msg = "Access denied (403). The server refused the request." |
| 921 | elif code is not None: |
| 922 | msg = f"The server returned an error ({code}). Check the URL and try again." |
| 923 | else: |
| 924 | msg = "The server returned an unexpected error. Check the URL and try again." |
| 925 | return Response( |
| 926 | {"valid": False, "errors": [msg]}, |
| 927 | status=status.HTTP_200_OK, |
| 928 | ) |
| 929 | except (json.JSONDecodeError, ValueError) as e: |
| 930 | msg = str(e) |
| 931 | # Pass through messages from _validate_fetch_url and _fetch_manifest |
| 932 | # as-is; only substitute the generic JSON message for actual parse errors. |
nothing calls this directly
no test coverage detected