Skip to content

Commit bb5a437

Browse files
HugoPBritoAlan-TheGentlemanalejandrobailo
authored
feat(ui): add Cloudflare provider support (#9910)
Co-authored-by: Alan Buscaglia <gentlemanprogramming@gmail.com> Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com> Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
1 parent 9f6121b commit bb5a437

32 files changed

+1163
-67
lines changed

prowler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
4949
- Update Azure Key Vault service metadata to new format [(#9621)](https://github.com/prowler-cloud/prowler/pull/9621)
5050
- Update Azure Entra ID service metadata to new format [(#9619)](https://github.com/prowler-cloud/prowler/pull/9619)
5151
- Update Azure Virtual Machines service metadata to new format [(#9629)](https://github.com/prowler-cloud/prowler/pull/9629)
52+
- Cloudflare provider credential validation with specific exceptions [(#9910)](https://github.com/prowler-cloud/prowler/pull/9910)
5253

5354
### 🔐 Security
5455

prowler/providers/cloudflare/cloudflare_provider.py

Lines changed: 289 additions & 6 deletions
Large diffs are not rendered by default.

prowler/providers/cloudflare/exceptions/exceptions.py

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,38 @@ class CloudflareBaseException(ProwlerException):
3434
"message": "Cloudflare API call failed",
3535
"remediation": "Inspect the API response details and permissions for the failing request.",
3636
},
37-
(9007, "CloudflareCredentialsConflictError"): {
38-
"message": "Conflicting Cloudflare credentials provided",
39-
"remediation": "Use either API Token or API Key + Email, not both. Unset CLOUDFLARE_API_TOKEN or unset both CLOUDFLARE_API_KEY and CLOUDFLARE_API_EMAIL.",
37+
(9007, "CloudflareNoAccountsError"): {
38+
"message": "No Cloudflare accounts found",
39+
"remediation": "Verify your API token has the required permissions to list accounts.",
40+
},
41+
(9008, "CloudflareUserTokenRequiredError"): {
42+
"message": "User-level API token required",
43+
"remediation": "Create a User API Token under My Profile (not an Account-owned token), or use API Key + Email authentication.",
44+
},
45+
(9009, "CloudflareInvalidAPIKeyError"): {
46+
"message": "Invalid API Key or Email",
47+
"remediation": "Verify your API Key and Email are correct. The API Key can be found in your Cloudflare profile.",
48+
},
49+
(9010, "CloudflareInvalidAPITokenError"): {
50+
"message": "Invalid API Token format",
51+
"remediation": "Check that your API Token is correctly formatted. Tokens should be alphanumeric strings.",
52+
},
53+
(9011, "CloudflareRateLimitError"): {
54+
"message": "Cloudflare API rate limit exceeded",
55+
"remediation": "Wait before retrying. Consider reducing the frequency of API calls.",
4056
},
4157
}
4258

4359
def __init__(self, code, file=None, original_exception=None, message=None):
4460
provider = "Cloudflare"
4561
error_info = self.CLOUDFLARE_ERROR_CODES.get((code, self.__class__.__name__))
46-
if message:
62+
if error_info is None:
63+
error_info = {
64+
"message": message or "Unknown Cloudflare error",
65+
"remediation": "Check the Cloudflare API documentation for more details.",
66+
}
67+
elif message:
68+
error_info = error_info.copy()
4769
error_info["message"] = message
4870
super().__init__(
4971
code=code,
@@ -117,10 +139,46 @@ def __init__(self, file=None, original_exception=None, message=None):
117139
)
118140

119141

120-
class CloudflareCredentialsConflictError(CloudflareBaseException):
121-
"""Exception for conflicting Cloudflare credentials."""
142+
class CloudflareNoAccountsError(CloudflareBaseException):
143+
"""Exception for no Cloudflare accounts found."""
122144

123145
def __init__(self, file=None, original_exception=None, message=None):
124146
super().__init__(
125147
9007, file=file, original_exception=original_exception, message=message
126148
)
149+
150+
151+
class CloudflareUserTokenRequiredError(CloudflareBaseException):
152+
"""Exception for missing user-level Cloudflare authentication."""
153+
154+
def __init__(self, file=None, original_exception=None, message=None):
155+
super().__init__(
156+
9008, file=file, original_exception=original_exception, message=message
157+
)
158+
159+
160+
class CloudflareInvalidAPIKeyError(CloudflareBaseException):
161+
"""Exception for invalid Cloudflare API Key or Email."""
162+
163+
def __init__(self, file=None, original_exception=None, message=None):
164+
super().__init__(
165+
9009, file=file, original_exception=original_exception, message=message
166+
)
167+
168+
169+
class CloudflareInvalidAPITokenError(CloudflareBaseException):
170+
"""Exception for invalid Cloudflare API Token format."""
171+
172+
def __init__(self, file=None, original_exception=None, message=None):
173+
super().__init__(
174+
9010, file=file, original_exception=original_exception, message=message
175+
)
176+
177+
178+
class CloudflareRateLimitError(CloudflareBaseException):
179+
"""Exception for Cloudflare API rate limit exceeded."""
180+
181+
def __init__(self, file=None, original_exception=None, message=None):
182+
super().__init__(
183+
9011, file=file, original_exception=original_exception, message=message
184+
)

0 commit comments

Comments
 (0)