-
Notifications
You must be signed in to change notification settings - Fork 1
🛡️ Sentinel: [Security Enhancement] Harden input validation for IDs and Folder Names #151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -397,25 +397,34 @@ | |||||
| return text | ||||||
|
|
||||||
|
|
||||||
| def is_valid_profile_id_format(profile_id: str) -> bool: | ||||||
| if not re.match(r"^[a-zA-Z0-9_-]+$", profile_id): | ||||||
| return False | ||||||
| if len(profile_id) > 64: | ||||||
| def validate_resource_id( | ||||||
| resource_id: str, type_name: str = "ID", log_errors: bool = True | ||||||
Check warningCode scanning / Pylint (reported by Codacy) Wrong hanging indentation before block (add 4 spaces). Warning
Wrong hanging indentation before block (add 4 spaces).
|
||||||
| ) -> bool: | ||||||
| """ | ||||||
| Validates a resource ID (Profile ID, Folder ID/PK). | ||||||
| Allowed: Alphanumeric, hyphen, underscore. | ||||||
| Max Length: 64 | ||||||
| """ | ||||||
| if not resource_id: | ||||||
Check warningCode scanning / Pylint (reported by Codacy) Missing function docstring Warning
Missing function docstring
|
||||||
| return False | ||||||
| return True | ||||||
|
|
||||||
| if len(resource_id) > 64: | ||||||
| if log_errors: | ||||||
| log.error(f"Invalid {type_name} length (max 64 chars)") | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
Check warningCode scanning / Prospector (reported by Codacy) Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning
Use lazy % formatting in logging functions (logging-fstring-interpolation)
|
||||||
| return False | ||||||
|
|
||||||
| def validate_profile_id(profile_id: str, log_errors: bool = True) -> bool: | ||||||
| if not is_valid_profile_id_format(profile_id): | ||||||
| if not re.match(r"^[a-zA-Z0-9_-]+$", resource_id): | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The regular expression used for validation uses the
Suggested change
Comment on lines
+411
to
+416
|
||||||
| if log_errors: | ||||||
| if not re.match(r"^[a-zA-Z0-9_-]+$", profile_id): | ||||||
| log.error("Invalid profile ID format (contains unsafe characters)") | ||||||
| elif len(profile_id) > 64: | ||||||
| log.error("Invalid profile ID length (max 64 chars)") | ||||||
| log.error(f"Invalid {type_name} format (contains unsafe characters)") | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
Check warningCode scanning / Prospector (reported by Codacy) Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning
Use lazy % formatting in logging functions (logging-fstring-interpolation)
|
||||||
| return False | ||||||
|
|
||||||
| return True | ||||||
|
|
||||||
|
|
||||||
| def validate_profile_id(profile_id: str, log_errors: bool = True) -> bool: | ||||||
| return validate_resource_id(profile_id, "profile ID", log_errors) | ||||||
|
|
||||||
|
|
||||||
| def is_valid_rule(rule: str) -> bool: | ||||||
| """ | ||||||
| Validates that a rule is safe to use. | ||||||
|
|
@@ -436,15 +445,17 @@ | |||||
| def is_valid_folder_name(name: str) -> bool: | ||||||
| """ | ||||||
| Validates folder name to prevent XSS and ensure printability. | ||||||
| Allowed: Anything printable except < > " ' ` | ||||||
| Allowed: Alphanumeric, space, hyphen, dot, underscore, parens, brackets, braces. | ||||||
| Max Length: 64 | ||||||
| """ | ||||||
| if not name or not name.strip() or not name.isprintable(): | ||||||
| return False | ||||||
|
|
||||||
| # Block XSS and HTML injection characters | ||||||
| # Allow: ( ) [ ] { } for folder names (e.g. "Work (Private)") | ||||||
| dangerous_chars = set("<>\"'`") | ||||||
| if any(c in dangerous_chars for c in name): | ||||||
| if len(name) > 64: | ||||||
| return False | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
|
|
||||||
| # Whitelist: Alphanumeric, space, hyphen, dot, underscore, parens, brackets, braces | ||||||
| if not re.match(r"^[a-zA-Z0-9 \-_.()\[\]{}]+$", name): | ||||||
| return False | ||||||
|
|
||||||
| return True | ||||||
|
|
@@ -461,7 +472,7 @@ | |||||
| return False | ||||||
| if not isinstance(data["group"], dict): | ||||||
| log.error( | ||||||
| f"Invalid data from {sanitize_for_log(url)}: 'group' must be an object." | ||||||
Check warningCode scanning / Prospector (reported by Codacy) Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning
Use lazy % formatting in logging functions (logging-fstring-interpolation)
|
||||||
| ) | ||||||
| return False | ||||||
| if "group" not in data["group"]: | ||||||
|
|
@@ -627,11 +638,18 @@ | |||||
| try: | ||||||
| data = _api_get(client, f"{API_BASE}/{profile_id}/groups").json() | ||||||
| folders = data.get("body", {}).get("groups", []) | ||||||
| return { | ||||||
| f["group"].strip(): f["PK"] | ||||||
| for f in folders | ||||||
| if f.get("group") and f.get("PK") | ||||||
| } | ||||||
| result = {} | ||||||
| for f in folders: | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "f" doesn't conform to snake_case naming style Warning
Variable name "f" doesn't conform to snake_case naming style
Check warningCode scanning / Pylint (reported by Codacy) Variable name "f" doesn't conform to snake_case naming style Warning
Variable name "f" doesn't conform to snake_case naming style
|
||||||
| name = f.get("group") | ||||||
| pk = f.get("PK") | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
Check warningCode scanning / Pylint (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
|
||||||
| if name and pk: | ||||||
| if validate_resource_id(pk, "Folder PK", log_errors=False): | ||||||
| result[name.strip()] = pk | ||||||
| else: | ||||||
| log.warning( | ||||||
|
||||||
| f"Skipping folder '{sanitize_for_log(name)}' with unsafe PK: {sanitize_for_log(pk)}" | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Line too long (108/100) Warning
Line too long (108/100)
Check warningCode scanning / Pylint (reported by Codacy) Line too long (108/100) Warning
Line too long (108/100)
|
||||||
| ) | ||||||
|
Comment on lines
+641
to
+651
|
||||||
| return result | ||||||
| except (httpx.HTTPError, KeyError) as e: | ||||||
| log.error(f"Failed to list existing folders: {sanitize_for_log(e)}") | ||||||
| return {} | ||||||
|
|
@@ -725,7 +743,7 @@ | |||||
| return None | ||||||
|
|
||||||
| completed = 0 | ||||||
| with concurrent.futures.ThreadPoolExecutor() as executor: | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
| futures = { | ||||||
| executor.submit(_validate_and_fetch, url): url for url in urls_to_process | ||||||
| } | ||||||
|
|
@@ -746,7 +764,7 @@ | |||||
| log.warning( | ||||||
| f"Failed to pre-fetch {sanitize_for_log(futures[future])}: {e}" | ||||||
| ) | ||||||
| # Restore progress bar after warning | ||||||
Check warningCode scanning / Prospector (reported by Codacy) Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning
Use lazy % formatting in logging functions (logging-fstring-interpolation)
|
||||||
| render_progress_bar(completed, total, "Warming up cache", prefix="⏳") | ||||||
|
|
||||||
| if USE_COLORS: | ||||||
|
|
@@ -759,6 +777,10 @@ | |||||
| def delete_folder( | ||||||
| client: httpx.Client, profile_id: str, name: str, folder_id: str | ||||||
| ) -> bool: | ||||||
| if not validate_resource_id(folder_id, "Folder ID to delete"): | ||||||
| log.error(f"Aborting deletion of {sanitize_for_log(name)}: Unsafe Folder ID") | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
Check warningCode scanning / Prospector (reported by Codacy) Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning
Use lazy % formatting in logging functions (logging-fstring-interpolation)
|
||||||
| return False | ||||||
|
Comment on lines
+780
to
+782
|
||||||
|
|
||||||
| try: | ||||||
| _api_delete(client, f"{API_BASE}/{profile_id}/groups/{folder_id}") | ||||||
| log.info("Deleted folder %s (ID %s)", sanitize_for_log(name), folder_id) | ||||||
|
|
@@ -770,44 +792,57 @@ | |||||
| return False | ||||||
|
|
||||||
|
|
||||||
| def create_folder( | ||||||
| client: httpx.Client, profile_id: str, name: str, do: int, status: int | ||||||
| ) -> Optional[str]: | ||||||
| """ | ||||||
| Create a new folder and return its ID. | ||||||
| Attempts to read ID from response first, then falls back to polling. | ||||||
| """ | ||||||
| try: | ||||||
| # 1. Send the Create Request | ||||||
| response = _api_post( | ||||||
| client, | ||||||
| f"{API_BASE}/{profile_id}/groups", | ||||||
| data={"name": name, "do": do, "status": status}, | ||||||
| ) | ||||||
|
|
||||||
| # OPTIMIZATION: Try to grab ID directly from response to avoid the wait loop | ||||||
| try: | ||||||
| resp_data = response.json() | ||||||
| body = resp_data.get("body", {}) | ||||||
|
|
||||||
| # Check if it returned a single group object | ||||||
| if isinstance(body, dict) and "group" in body and "PK" in body["group"]: | ||||||
| pk = body["group"]["PK"] | ||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Direct]", sanitize_for_log(name), pk | ||||||
| ) | ||||||
| return str(pk) | ||||||
| if validate_resource_id(str(pk), "New Folder PK"): | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
Check warningCode scanning / Pylint (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
|
||||||
Check warningCode scanning / Prospector (reported by Codacy) Unnecessary "else" after "return" (no-else-return) Warning
Unnecessary "else" after "return" (no-else-return)
|
||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Direct]", sanitize_for_log(name), pk | ||||||
| ) | ||||||
| return str(pk) | ||||||
|
Comment on lines
+818
to
+822
|
||||||
| else: | ||||||
| log.error( | ||||||
| f"API returned unsafe PK for folder {sanitize_for_log(name)}: {sanitize_for_log(pk)}" | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Line too long (109/100) Warning
Line too long (109/100)
Check warningCode scanning / Pylint (reported by Codacy) Line too long (109/100) Warning
Line too long (109/100)
|
||||||
| ) | ||||||
| return None | ||||||
|
Comment on lines
816
to
+827
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block of code for validating the returned For example: def _validate_and_log_pk(pk: Any, source: str) -> Optional[str]:
pk_str = str(pk)
if validate_resource_id(pk_str, f"{source} Folder PK"):
log.info(
"Created folder %s (ID %s) [%s]", sanitize_for_log(name), pk, source
)
return pk_str
else:
log.error(
f"API returned unsafe PK for folder {sanitize_for_log(name)}: {sanitize_for_log(pk)}"
)
return NoneThis helper could then be called from all three locations, simplifying the main function body. |
||||||
|
|
||||||
| # Check if it returned a list containing our group | ||||||
| if isinstance(body, dict) and "groups" in body: | ||||||
| for grp in body["groups"]: | ||||||
| if grp.get("group") == name: | ||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Direct]", | ||||||
| sanitize_for_log(name), | ||||||
| grp["PK"], | ||||||
| ) | ||||||
| return str(grp["PK"]) | ||||||
| pk = grp["PK"] | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
Check warningCode scanning / Pylint (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
|
||||||
| if validate_resource_id(str(pk), "New Folder PK"): | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
Check warningCode scanning / Pylint (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
|
||||||
Check warningCode scanning / Prospector (reported by Codacy) Unnecessary "else" after "return" (no-else-return) Warning
Unnecessary "else" after "return" (no-else-return)
|
||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Direct]", | ||||||
| sanitize_for_log(name), | ||||||
| pk, | ||||||
| ) | ||||||
| return str(pk) | ||||||
| else: | ||||||
| log.error( | ||||||
| f"API returned unsafe PK for folder {sanitize_for_log(name)}: {sanitize_for_log(pk)}" | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Line too long (117/100) Warning
Line too long (117/100)
Check warningCode scanning / Pylint (reported by Codacy) Line too long (117/100) Warning
Line too long (117/100)
|
||||||
| ) | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
| return None | ||||||
| except Exception as e: | ||||||
| log.debug(f"Could not extract ID from POST response: {e}") | ||||||
|
|
||||||
|
|
@@ -819,12 +854,19 @@ | |||||
|
|
||||||
| for grp in groups: | ||||||
| if grp["group"].strip() == name.strip(): | ||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Polled]", | ||||||
| sanitize_for_log(name), | ||||||
| grp["PK"], | ||||||
| ) | ||||||
| return str(grp["PK"]) | ||||||
| pk = grp["PK"] | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
Check warningCode scanning / Pylint (reported by Codacy) Variable name "pk" doesn't conform to snake_case naming style Warning
Variable name "pk" doesn't conform to snake_case naming style
|
||||||
| if validate_resource_id(str(pk), "Polled Folder PK"): | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
Check warningCode scanning / Pylint (reported by Codacy) Unnecessary "else" after "return" Warning
Unnecessary "else" after "return"
|
||||||
|
||||||
| log.info( | ||||||
| "Created folder %s (ID %s) [Polled]", | ||||||
| sanitize_for_log(name), | ||||||
| pk, | ||||||
| ) | ||||||
| return str(pk) | ||||||
| else: | ||||||
| log.error( | ||||||
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Use lazy % formatting in logging functions Note
Use lazy % formatting in logging functions
|
||||||
|
||||||
| f"API returned unsafe PK for folder {sanitize_for_log(name)}: {sanitize_for_log(pk)}" | ||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Line too long (117/100) Warning
Line too long (117/100)
Check warningCode scanning / Pylint (reported by Codacy) Line too long (117/100) Warning
Line too long (117/100)
|
||||||
| ) | ||||||
| return None | ||||||
| except Exception as e: | ||||||
| log.warning(f"Error fetching groups on attempt {attempt}: {e}") | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||
| from unittest.mock import MagicMock | ||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Missing module docstring Warning test
Missing module docstring
Check warningCode scanning / Pylint (reported by Codacy) Missing module docstring Warning test
Missing module docstring
Check noticeCode scanning / Pylintpython3 (reported by Codacy) Unused MagicMock imported from unittest.mock Note test
Unused MagicMock imported from unittest.mock
Check noticeCode scanning / Pylint (reported by Codacy) Unused MagicMock imported from unittest.mock Note test
Unused MagicMock imported from unittest.mock
|
||||
Check warningCode scanning / Prospector (reported by Codacy) Unused MagicMock imported from unittest.mock (unused-import) Warning test
Unused MagicMock imported from unittest.mock (unused-import)
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||
| from unittest.mock import MagicMock |
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylint (reported by Codacy)
Line too long (112/100) Warning test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Line too long (112/100) Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check warning
Code scanning / Pylint (reported by Codacy)
Missing function docstring Warning test
Check warning
Code scanning / Pylintpython3 (reported by Codacy)
Missing function or method docstring Warning test
Check notice
Code scanning / Bandit
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
Check notice
Code scanning / Bandit (reported by Codacy)
Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type hint for
resource_idisstr, but the function's logic correctly handlesNoneand the new tests passNoneas a valid input. To align the function signature with its implementation and tests, and to satisfy static type checkers, the type hint should be changed toOptional[str]. TheOptionaltype is already imported in this file.