mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user