From 4db876ec19fe7fa457f60c4d339e831e9ca031ba Mon Sep 17 00:00:00 2001 From: Douglas Coburn Date: Fri, 21 Nov 2025 07:37:21 -0800 Subject: [PATCH 1/2] Since the API Changes to not accept unsupported files changed the temp scan file to be .socket.facts.json to pass the validator. Also, added the debug flag support to the reachability engine --- pyproject.toml | 2 +- socketsecurity/__init__.py | 2 +- socketsecurity/core/__init__.py | 11 ++++++----- socketsecurity/core/tools/reachability.py | 5 +++++ socketsecurity/socketcli.py | 3 ++- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3060502..f3e1309 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "socketsecurity" -version = "2.2.33" +version = "2.2.34" requires-python = ">= 3.10" license = {"file" = "LICENSE"} dependencies = [ diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index 3d95bbf..3ff39d7 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,3 +1,3 @@ __author__ = 'socket.dev' -__version__ = '2.2.33' +__version__ = '2.2.34' USER_AGENT = f'SocketPythonCLI/{__version__}' diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 1261c43..735ed8b 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -442,12 +442,13 @@ def empty_head_scan_file() -> List[str]: Returns: List containing path to a temporary empty file """ - # Create a temporary empty file - temp_fd, temp_path = tempfile.mkstemp(suffix='.empty', prefix='socket_baseline_') + # Create a temporary directory and then create our specific filename + temp_dir = tempfile.gettempdir() + temp_path = os.path.join(temp_dir, '.socket.facts.json') - # Close the file descriptor since we just need the path - # The file is already created and empty - os.close(temp_fd) + # Create the empty file + with open(temp_path, 'w') as f: + pass # Creates an empty file log.debug(f"Created temporary empty file for baseline scan: {temp_path}") return [temp_path] diff --git a/socketsecurity/core/tools/reachability.py b/socketsecurity/core/tools/reachability.py index 4eb305c..c2db837 100644 --- a/socketsecurity/core/tools/reachability.py +++ b/socketsecurity/core/tools/reachability.py @@ -100,6 +100,7 @@ def run_reachability_analysis( concurrency: Optional[int] = None, additional_params: Optional[List[str]] = None, allow_unverified: bool = False, + enable_debug: bool = False, ) -> Dict[str, Any]: """ Run reachability analysis. @@ -123,6 +124,7 @@ def run_reachability_analysis( concurrency: Concurrency level for analysis (must be >= 1) additional_params: Additional parameters to pass to coana CLI allow_unverified: Disable SSL certificate verification (sets NODE_TLS_REJECT_UNAUTHORIZED=0) + enable_debug: Enable debug mode (passes -d flag to coana CLI) Returns: Dict containing scan_id and report_path @@ -173,6 +175,9 @@ def run_reachability_analysis( if concurrency: cmd.extend(["--concurrency", str(concurrency)]) + if enable_debug: + cmd.append("-d") + # Add any additional parameters provided by the user if additional_params: cmd.extend(additional_params) diff --git a/socketsecurity/socketcli.py b/socketsecurity/socketcli.py index c01c48e..244402e 100644 --- a/socketsecurity/socketcli.py +++ b/socketsecurity/socketcli.py @@ -288,7 +288,8 @@ def main_code(): version=config.reach_version, concurrency=config.reach_concurrency, additional_params=config.reach_additional_params, - allow_unverified=config.allow_unverified + allow_unverified=config.allow_unverified, + enable_debug=config.enable_debug ) log.info(f"Reachability analysis completed successfully") From 1677e61dc5c3316ee3d94b08bb90ab7e9ede1c16 Mon Sep 17 00:00:00 2001 From: Douglas Coburn Date: Fri, 21 Nov 2025 07:49:34 -0800 Subject: [PATCH 2/2] Fix if there is no supported manifest files --- pyproject.toml | 2 +- socketsecurity/__init__.py | 2 +- socketsecurity/core/__init__.py | 77 +++++++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f3e1309..15aac71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "socketsecurity" -version = "2.2.34" +version = "2.2.35" requires-python = ">= 3.10" license = {"file" = "LICENSE"} dependencies = [ diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index 3ff39d7..451b3f1 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,3 +1,3 @@ __author__ = 'socket.dev' -__version__ = '2.2.34' +__version__ = '2.2.35' USER_AGENT = f'SocketPythonCLI/{__version__}' diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 735ed8b..443c5cf 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -525,18 +525,42 @@ def create_full_scan_with_report_url( if save_manifest_tar_path and all_files and paths: self.save_manifest_tar(all_files, save_manifest_tar_path, paths[0]) + # If no supported files found, create empty scan if not all_files: - return diff - - try: - # Create new scan - new_scan_start = time.time() - new_full_scan = self.create_full_scan(all_files, params, base_paths=base_paths) - new_scan_end = time.time() - log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}") - except APIFailure as e: - log.error(f"Failed to create full scan: {e}") - raise + log.info("No supported manifest files found - creating empty scan") + empty_files = Core.empty_head_scan_file() + try: + # Create new scan + new_scan_start = time.time() + new_full_scan = self.create_full_scan(empty_files, params, base_paths=base_paths) + new_scan_end = time.time() + log.info(f"Total time to create empty full scan: {new_scan_end - new_scan_start:.2f}") + + # Clean up the temporary empty file + for temp_file in empty_files: + try: + os.unlink(temp_file) + log.debug(f"Cleaned up temporary file: {temp_file}") + except OSError as e: + log.warning(f"Failed to clean up temporary file {temp_file}: {e}") + except Exception as e: + # Clean up temp files even if scan creation fails + for temp_file in empty_files: + try: + os.unlink(temp_file) + except OSError: + pass + raise e + else: + try: + # Create new scan + new_scan_start = time.time() + new_full_scan = self.create_full_scan(all_files, params, base_paths=base_paths) + new_scan_end = time.time() + log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}") + except APIFailure as e: + log.error(f"Failed to create full scan: {e}") + raise # Construct report URL base_socket = "https://socket.dev/dashboard/org" @@ -889,8 +913,11 @@ def create_new_diff( if save_manifest_tar_path and all_files and paths: self.save_manifest_tar(all_files, save_manifest_tar_path, paths[0]) + # If no supported files found, create empty scan for comparison + scan_files = all_files if not all_files: - return Diff(id="NO_DIFF_RAN", diff_url="", report_url="") + log.info("No supported manifest files found - creating empty scan for diff comparison") + scan_files = Core.empty_head_scan_file() try: # Get head scan ID @@ -933,19 +960,43 @@ def create_new_diff( raise e # Create new scan + temp_files_to_cleanup = [] + if not all_files: # We're using empty scan files + temp_files_to_cleanup = scan_files + try: new_scan_start = time.time() - new_full_scan = self.create_full_scan(all_files, params, base_paths=base_paths) + new_full_scan = self.create_full_scan(scan_files, params, base_paths=base_paths) new_scan_end = time.time() log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}") except APIFailure as e: log.error(f"API Error: {e}") + # Clean up temp files if any + for temp_file in temp_files_to_cleanup: + try: + os.unlink(temp_file) + except OSError: + pass sys.exit(1) except Exception as e: import traceback log.error(f"Error creating new full scan: {str(e)}") log.error(f"Stack trace:\n{traceback.format_exc()}") + # Clean up temp files if any + for temp_file in temp_files_to_cleanup: + try: + os.unlink(temp_file) + except OSError: + pass raise + finally: + # Clean up temporary empty files if they were created + for temp_file in temp_files_to_cleanup: + try: + os.unlink(temp_file) + log.debug(f"Cleaned up temporary file: {temp_file}") + except OSError as e: + log.warning(f"Failed to clean up temporary file {temp_file}: {e}") # Handle diff generation - now we always have both scans scans_ready = self.check_full_scans_status(head_full_scan_id, new_full_scan.id)