diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 77f078c..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,20 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7e8ad3d0508bf0c279a648ee7a1873fc16334cf0b711f30b2dc54a1da68fef6c" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.12" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/socketsecurity", - "verify_ssl": true - } - ] - }, - "default": {}, - "develop": {} -} diff --git a/pyproject.toml b/pyproject.toml index 9ec3c0f..6b2ea18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "socketsecurity" -version = "2.2.12" +version = "2.2.15" requires-python = ">= 3.10" license = {"file" = "LICENSE"} dependencies = [ diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index aecfb7d..c4b1ae5 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,2 +1,3 @@ __author__ = 'socket.dev' -__version__ = '2.2.12' +__version__ = '2.2.15' +USER_AGENT = f'SocketPythonCLI/{__version__}' diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 6dd6ecb..1261c43 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -18,7 +18,7 @@ from socketdev.repos import RepositoryInfo from socketdev.settings import SecurityPolicyRule import copy -from socketsecurity import __version__ +from socketsecurity import __version__, USER_AGENT from socketsecurity.core.classes import ( Alert, Diff, @@ -39,6 +39,7 @@ "Core", "log", "__version__", + "USER_AGENT", ] version = __version__ diff --git a/socketsecurity/core/cli_client.py b/socketsecurity/core/cli_client.py index bf8db38..8bb2ed6 100644 --- a/socketsecurity/core/cli_client.py +++ b/socketsecurity/core/cli_client.py @@ -4,6 +4,7 @@ import requests +from socketsecurity import USER_AGENT from .exceptions import APIFailure from .socket_config import SocketConfig @@ -31,7 +32,7 @@ def request( default_headers = { 'Authorization': f"Basic {self._encoded_key}", - 'User-Agent': 'SocketPythonCLI/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } diff --git a/socketsecurity/core/resource_utils.py b/socketsecurity/core/resource_utils.py index 2652bbf..b49cc2e 100644 --- a/socketsecurity/core/resource_utils.py +++ b/socketsecurity/core/resource_utils.py @@ -1,8 +1,17 @@ """ System resource utilities for the Socket Security CLI. """ -import resource import logging +import sys + +# The resource module is only available on Unix-like systems +resource_available = False +try: + import resource + resource_available = True +except ImportError: + # On Windows, the resource module is not available + pass log = logging.getLogger("socketdev") @@ -10,10 +19,14 @@ def get_file_descriptor_limit(): """ Get the current file descriptor limit (equivalent to ulimit -n) - + Returns: - tuple: (soft_limit, hard_limit) or (None, None) if error + tuple: (soft_limit, hard_limit) or (None, None) if error or on Windows """ + if not resource_available: + # On Windows, resource module is not available + return None, None + try: soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE) return soft_limit, hard_limit @@ -25,26 +38,26 @@ def get_file_descriptor_limit(): def check_file_count_against_ulimit(file_count, buffer_size=100): """ Check if the number of files would exceed the file descriptor limit - + Args: file_count (int): Number of files to check buffer_size (int): Safety buffer to leave for other file operations - + Returns: dict: Information about the check """ soft_limit, hard_limit = get_file_descriptor_limit() - + if soft_limit is None: return { "can_check": False, "error": "Could not determine file descriptor limit", "safe_to_process": True # Assume safe if we can't check } - + available_fds = soft_limit - buffer_size would_exceed = file_count > available_fds - + return { "can_check": True, "file_count": file_count, diff --git a/socketsecurity/core/scm/client.py b/socketsecurity/core/scm/client.py index 1033613..0575711 100644 --- a/socketsecurity/core/scm/client.py +++ b/socketsecurity/core/scm/client.py @@ -1,6 +1,7 @@ from abc import abstractmethod from typing import Dict +from socketsecurity import USER_AGENT from ..cli_client import CliClient @@ -28,7 +29,7 @@ class GithubClient(ScmClient): def get_headers(self) -> Dict: return { 'Authorization': f"Bearer {self.token}", - 'User-Agent': 'SocketPythonScript/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } @@ -52,7 +53,7 @@ def _get_gitlab_auth_headers(token: str) -> dict: import os base_headers = { - 'User-Agent': 'SocketPythonScript/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } diff --git a/socketsecurity/core/scm/github.py b/socketsecurity/core/scm/github.py index 1b4fa0e..0870f5c 100644 --- a/socketsecurity/core/scm/github.py +++ b/socketsecurity/core/scm/github.py @@ -5,6 +5,7 @@ from git import Optional +from socketsecurity import USER_AGENT from socketsecurity.core import log from socketsecurity.core.classes import Comment from socketsecurity.core.scm_comments import Comments @@ -83,7 +84,7 @@ def from_env(cls, pr_number: Optional[str] = None) -> 'GithubConfig': event_action=event_action, headers={ 'Authorization': f"Bearer {token}", - 'User-Agent': 'SocketPythonScript/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } ) diff --git a/socketsecurity/core/scm/gitlab.py b/socketsecurity/core/scm/gitlab.py index b5f46b7..c8aba49 100644 --- a/socketsecurity/core/scm/gitlab.py +++ b/socketsecurity/core/scm/gitlab.py @@ -3,6 +3,7 @@ from dataclasses import dataclass from typing import Optional +from socketsecurity import USER_AGENT from socketsecurity.core import log from socketsecurity.core.classes import Comment from socketsecurity.core.scm_comments import Comments @@ -79,7 +80,7 @@ def _get_auth_headers(token: str) -> dict: - Other tokens: Use PRIVATE-TOKEN as fallback """ base_headers = { - 'User-Agent': 'SocketPythonScript/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } @@ -150,7 +151,7 @@ def _get_fallback_headers(self, original_headers: dict) -> dict: If using Bearer, fallback to PRIVATE-TOKEN and vice versa. """ base_headers = { - 'User-Agent': 'SocketPythonScript/0.0.1', + 'User-Agent': USER_AGENT, "accept": "application/json" } @@ -171,11 +172,11 @@ def _get_fallback_headers(self, original_headers: dict) -> dict: } # No fallback available - return None + return {} def check_event_type(self) -> str: pipeline_source = self.config.pipeline_source.lower() - if pipeline_source in ["web", 'merge_request_event', "push", "api"]: + if pipeline_source in ["web", 'merge_request_event', "push", "api", 'pipeline']: if not self.config.mr_iid: return "main" return "diff" @@ -234,8 +235,8 @@ def add_socket_comments( new_security_comment: bool = True, new_overview_comment: bool = True ) -> None: - existing_overview_comment = comments.get("overview") - existing_security_comment = comments.get("security") + existing_overview_comment = comments.get("overview", "") + existing_security_comment = comments.get("security", "") if new_overview_comment: log.debug("New Dependency Overview comment") if existing_overview_comment is not None: @@ -256,7 +257,7 @@ def add_socket_comments( self.post_comment(security_comment) def remove_comment_alerts(self, comments: dict): - security_alert = comments.get("security") + security_alert = comments.get("security", "") if security_alert is not None: security_alert: Comment new_body = Comments.process_security_comment(security_alert, comments) diff --git a/socketsecurity/socketcli.py b/socketsecurity/socketcli.py index 2813790..79b8374 100644 --- a/socketsecurity/socketcli.py +++ b/socketsecurity/socketcli.py @@ -114,7 +114,7 @@ def main_code(): # Git setup is_repo = False - git_repo = None + git_repo: Git try: git_repo = Git(config.target_path) is_repo = True diff --git a/tests/unit/test_gitlab_auth.py b/tests/unit/test_gitlab_auth.py index be34224..3c6d6dd 100644 --- a/tests/unit/test_gitlab_auth.py +++ b/tests/unit/test_gitlab_auth.py @@ -3,6 +3,7 @@ import pytest from unittest.mock import patch, MagicMock +from socketsecurity import USER_AGENT from socketsecurity.core.scm.gitlab import GitlabConfig @@ -58,7 +59,7 @@ def test_all_headers_include_base_headers(self): for token in test_tokens: headers = GitlabConfig._get_auth_headers(token) - assert headers['User-Agent'] == 'SocketPythonScript/0.0.1' + assert headers['User-Agent'] == USER_AGENT assert headers['accept'] == 'application/json' @patch.dict(os.environ, {'CI_JOB_TOKEN': 'ci-token-123'})