fix: Remove type validation while updating provider credentials (#8197)

Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
This commit is contained in:
Pepe Fagoaga
2025-07-08 11:42:02 +02:00
committed by GitHub
parent 4c50f4d811
commit fe00b788cc
8 changed files with 115 additions and 43 deletions
+3
View File
@@ -14,6 +14,9 @@ All notable changes to the **Prowler API** are documented in this file.
### Fixed
- Scan with no resources will not trigger legacy code for findings metadata [(#8183)](https://github.com/prowler-cloud/prowler/pull/8183)
### Removed
- Validation of the provider's secret type during updates [(#8197)](https://github.com/prowler-cloud/prowler/pull/8197)
---
## [v1.9.0] (Prowler v5.8.0)
-2
View File
@@ -9863,7 +9863,6 @@ components:
* `static` - Key-value pairs
* `role` - Role assumption
* `service_account` - GCP Service Account Key
readOnly: true
secret:
oneOf:
- type: object
@@ -11621,7 +11620,6 @@ components:
* `static` - Key-value pairs
* `role` - Role assumption
* `service_account` - GCP Service Account Key
readOnly: true
secret:
oneOf:
- type: object
+98
View File
@@ -2038,6 +2038,104 @@ class TestProviderSecretViewSet:
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_provider_secrets_partial_update_with_secret_type(
self, authenticated_client, provider_secret_fixture
):
provider_secret, *_ = provider_secret_fixture
data = {
"data": {
"type": "provider-secrets",
"id": str(provider_secret.id),
"attributes": {
"name": "new_name",
"secret": {
"service_account_key": {},
},
"secret_type": "service_account",
},
"relationships": {
"provider": {
"data": {
"type": "providers",
"id": str(provider_secret.provider.id),
}
}
},
}
}
response = authenticated_client.patch(
reverse("providersecret-detail", kwargs={"pk": provider_secret.id}),
data=json.dumps(data),
content_type="application/vnd.api+json",
)
assert response.status_code == status.HTTP_200_OK
provider_secret.refresh_from_db()
assert provider_secret.name == "new_name"
assert provider_secret.secret == {"service_account_key": {}}
def test_provider_secrets_partial_update_with_invalid_secret_type(
self, authenticated_client, provider_secret_fixture
):
provider_secret, *_ = provider_secret_fixture
data = {
"data": {
"type": "provider-secrets",
"id": str(provider_secret.id),
"attributes": {
"name": "new_name",
"secret": {
"service_account_key": {},
},
"secret_type": "static",
},
"relationships": {
"provider": {
"data": {
"type": "providers",
"id": str(provider_secret.provider.id),
}
}
},
}
}
response = authenticated_client.patch(
reverse("providersecret-detail", kwargs={"pk": provider_secret.id}),
data=json.dumps(data),
content_type="application/vnd.api+json",
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_provider_secrets_partial_update_without_secret_type_but_different(
self, authenticated_client, provider_secret_fixture
):
provider_secret, *_ = provider_secret_fixture
data = {
"data": {
"type": "provider-secrets",
"id": str(provider_secret.id),
"attributes": {
"name": "new_name",
"secret": {
"service_account_key": {},
},
},
"relationships": {
"provider": {
"data": {
"type": "providers",
"id": str(provider_secret.provider.id),
}
}
},
}
}
response = authenticated_client.patch(
reverse("providersecret-detail", kwargs={"pk": provider_secret.id}),
data=json.dumps(data),
content_type="application/vnd.api+json",
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
@pytest.mark.django_db
class TestScanViewSet:
+3 -2
View File
@@ -1315,12 +1315,13 @@ class ProviderSecretUpdateSerializer(BaseWriteProviderSecretSerializer):
"inserted_at": {"read_only": True},
"updated_at": {"read_only": True},
"provider": {"read_only": True},
"secret_type": {"read_only": True},
"secret_type": {"required": False},
}
def validate(self, attrs):
provider = self.instance.provider
secret_type = self.instance.secret_type
# To allow updating a secret with the same type without making the `secret_type` mandatory
secret_type = attrs.get("secret_type") or self.instance.secret_type
secret = attrs.get("secret")
validated_attrs = super().validate(attrs)
+8
View File
@@ -13,6 +13,14 @@ All notable changes to the **Prowler UI** are documented in this file.
- Upgrade to Next.js 14.2.30 and lock TypeScript to 5.5.4 for ESLint compatibility [(#8189)](https://github.com/prowler-cloud/prowler/pull/8189)
### 🐞 Fixed
### Removed
---
## [v1.8.1] (Prowler 5.8.1)
### Removed
- Validation of the provider's secret type during updates [(#8197)](https://github.com/prowler-cloud/prowler/pull/8197)
---
+2 -4
View File
@@ -13,7 +13,6 @@ import {
} from "@/lib";
import {
buildSecretConfig,
buildUpdateSecretConfig,
handleApiError,
handleApiResponse,
} from "@/lib/provider-credentials/build-crendentials";
@@ -194,8 +193,7 @@ export const updateCredentialsProvider = async (
) as ProviderType;
try {
const secret = buildUpdateSecretConfig(formData, providerType);
const { secretType, secret } = buildSecretConfig(formData, providerType);
const response = await fetch(url.toString(), {
method: "PATCH",
headers,
@@ -203,7 +201,7 @@ export const updateCredentialsProvider = async (
data: {
type: "provider-secrets",
id: credentialsId,
attributes: { secret },
attributes: { secret_type: secretType, secret },
},
}),
});
@@ -1,6 +1,5 @@
"use client";
import { InfoIcon } from "@/components/icons";
import { SelectViaAWS } from "@/components/providers/workflow/forms/select-credentials-type/aws";
import { SelectViaGCP } from "@/components/providers/workflow/forms/select-credentials-type/gcp";
import { ProviderType } from "@/types/providers";
@@ -24,28 +23,5 @@ export const CredentialsUpdateInfo = ({
return null;
};
return (
<div className="flex flex-col gap-4">
<p className="text-sm text-default-700">
To update provider credentials,{" "}
<strong>
the same type that was originally configured must be used.
</strong>
</p>
<div className="flex items-center rounded-lg border border-system-warning bg-system-warning-medium p-4 text-sm dark:text-default-300">
<InfoIcon className="mr-2 inline h-4 w-4 flex-shrink-0" />
<p>
If the provider was configured with static credentials, updates must
also use static credentials. If it was configured with a role in AWS
(or service account in GCP),{" "}
<strong>updates must use the same type.</strong>
</p>
</div>
<p className="text-sm font-bold text-default-700">
To switch from one type to another, the provider must be deleted and set
up again.
</p>
{renderSelectComponent()}
</div>
);
return <div className="flex flex-col gap-4">{renderSelectComponent()}</div>;
};
@@ -187,16 +187,6 @@ export const buildSecretConfig = (
return builder();
};
// Helper function to build secret for update (reuses existing logic)
export const buildUpdateSecretConfig = (
formData: FormData,
providerType: ProviderType,
) => {
// Reuse the same secret building logic as add
const { secret } = buildSecretConfig(formData, providerType);
return secret;
};
// Helper function to handle API responses consistently
export const handleApiResponse = async (
response: Response,