socketsecurity 1.0.34__tar.gz → 1.0.35__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {socketsecurity-1.0.34/socketsecurity.egg-info → socketsecurity-1.0.35}/PKG-INFO +5 -9
  2. socketsecurity-1.0.35/pyproject.toml +48 -0
  3. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/__init__.py +1 -1
  4. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/__init__.py +116 -118
  5. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/github.py +28 -25
  6. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/socketcli.py +7 -18
  7. {socketsecurity-1.0.34 → socketsecurity-1.0.35/socketsecurity.egg-info}/PKG-INFO +5 -9
  8. socketsecurity-1.0.35/socketsecurity.egg-info/requires.txt +6 -0
  9. socketsecurity-1.0.34/pyproject.toml +0 -130
  10. socketsecurity-1.0.34/socketsecurity.egg-info/requires.txt +0 -11
  11. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/LICENSE +0 -0
  12. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/README.md +0 -0
  13. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/setup.cfg +0 -0
  14. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/classes.py +0 -0
  15. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/exceptions.py +0 -0
  16. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/git_interface.py +0 -0
  17. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/gitlab.py +0 -0
  18. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/issues.py +0 -0
  19. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/licenses.py +0 -0
  20. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/messages.py +0 -0
  21. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity/core/scm_comments.py +0 -0
  22. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity.egg-info/SOURCES.txt +0 -0
  23. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity.egg-info/dependency_links.txt +0 -0
  24. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity.egg-info/entry_points.txt +0 -0
  25. {socketsecurity-1.0.34 → socketsecurity-1.0.35}/socketsecurity.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: socketsecurity
3
- Version: 1.0.34
3
+ Version: 1.0.35
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Author-email: Douglas Coburn <douglas@socket.dev>
6
6
  Maintainer-email: Douglas Coburn <douglas@socket.dev>
@@ -15,16 +15,12 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Requires-Python: >=3.9
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: requests>=2.32.0
19
- Requires-Dist: mdutils~=1.6.0
18
+ Requires-Dist: requests
19
+ Requires-Dist: mdutils
20
20
  Requires-Dist: prettytable
21
21
  Requires-Dist: argparse
22
- Requires-Dist: GitPython>=3.1.43
23
- Requires-Dist: packaging>=24.1
24
- Requires-Dist: python-dotenv>=1.0.1
25
- Requires-Dist: socket-sdk-python>=1.0.14
26
- Provides-Extra: dev
27
- Requires-Dist: ruff>=0.3.0; extra == "dev"
22
+ Requires-Dist: GitPython
23
+ Requires-Dist: packaging
28
24
 
29
25
  # Socket Security CLI
30
26
 
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "socketsecurity"
7
+ dynamic = ["version"]
8
+ requires-python = ">= 3.9"
9
+ dependencies = [
10
+ 'requests',
11
+ 'mdutils',
12
+ 'prettytable',
13
+ 'argparse',
14
+ 'GitPython',
15
+ 'packaging'
16
+ ]
17
+ readme = "README.md"
18
+ description = "Socket Security CLI for CI/CD"
19
+ keywords = ["socketsecurity", "socket.dev", "sca", "oss", "security"]
20
+ authors = [
21
+ {name = "Douglas Coburn", email = "douglas@socket.dev"}
22
+ ]
23
+ maintainers = [
24
+ {name = "Douglas Coburn", email = "douglas@socket.dev"}
25
+ ]
26
+ classifiers = [
27
+ "Development Status :: 4 - Beta",
28
+ "Intended Audience :: Developers",
29
+ "Programming Language :: Python :: 3.9",
30
+ "Programming Language :: Python :: 3.10",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ ]
34
+
35
+ [project.scripts]
36
+ socketcli = "socketsecurity.socketcli:cli"
37
+
38
+ [project.urls]
39
+ Homepage = "https://socket.dev"
40
+
41
+ [tool.setuptools.packages.find]
42
+ include = [
43
+ "socketsecurity",
44
+ "socketsecurity.core"
45
+ ]
46
+
47
+ [tool.setuptools.dynamic]
48
+ version = {attr = "socketsecurity.__version__"}
@@ -1,2 +1,2 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '1.0.34'
2
+ __version__ = '1.0.35'
@@ -2,9 +2,9 @@ import logging
2
2
  from pathlib import PurePath
3
3
 
4
4
  import requests
5
+ from urllib.parse import urlencode
5
6
  import base64
6
7
  import json
7
- from socketdev import socketdev
8
8
  from socketsecurity.core.exceptions import (
9
9
  APIFailure, APIKeyMissing, APIAccessDenied, APIInsufficientQuota, APIResourceNotFound, APICloudflareError
10
10
  )
@@ -12,6 +12,7 @@ from socketsecurity import __version__
12
12
  from socketsecurity.core.licenses import Licenses
13
13
  from socketsecurity.core.issues import AllIssues
14
14
  from socketsecurity.core.classes import (
15
+ Report,
15
16
  Issue,
16
17
  Package,
17
18
  Alert,
@@ -225,53 +226,34 @@ def do_request(
225
226
 
226
227
 
227
228
  class Core:
228
- _sdk = None
229
- _initialized = False
229
+ token: str
230
+ base_api_url: str
231
+ request_timeout: int
232
+ reports: list
230
233
 
231
- def __init__(self):
232
- raise NotImplementedError("Use Core.initialize() instead of instantiation")
233
-
234
- @classmethod
235
- def initialize(
236
- cls,
234
+ def __init__(
235
+ self,
237
236
  token: str,
238
237
  base_api_url: str = None,
239
238
  request_timeout: int = None,
240
239
  enable_all_alerts: bool = False,
241
240
  allow_unverified: bool = False
242
- ) -> None:
243
- """Initialize the Core class and set up global configuration"""
244
- if cls._initialized:
245
- return
246
-
247
- global allow_unverified_ssl, all_new_alerts
248
-
241
+ ):
242
+ global allow_unverified_ssl
249
243
  allow_unverified_ssl = allow_unverified
250
- cls._initialize_sdk(token)
251
- encode_key(token + ":")
252
-
253
- if base_api_url is not None:
254
- cls.set_api_url(base_api_url)
255
-
256
- if request_timeout is not None:
257
- cls.set_timeout(request_timeout)
258
-
244
+ self.token = token + ":"
245
+ encode_key(self.token)
246
+ self.socket_date_format = "%Y-%m-%dT%H:%M:%S.%fZ"
247
+ self.base_api_url = base_api_url
248
+ if self.base_api_url is not None:
249
+ Core.set_api_url(self.base_api_url)
250
+ self.request_timeout = request_timeout
251
+ if self.request_timeout is not None:
252
+ Core.set_timeout(self.request_timeout)
259
253
  if enable_all_alerts:
254
+ global all_new_alerts
260
255
  all_new_alerts = True
261
-
262
- cls._initialized = True
263
- cls.set_org_vars()
264
-
265
- @classmethod
266
- def _initialize_sdk(cls, token: str) -> None:
267
- if cls._sdk is None:
268
- cls._sdk = socketdev(token=token)
269
-
270
- @classmethod
271
- def get_sdk(cls) -> socketdev:
272
- if not cls._initialized:
273
- raise RuntimeError("Core not initialized - call Core.initialize() first")
274
- return cls._sdk
256
+ Core.set_org_vars()
275
257
 
276
258
  @staticmethod
277
259
  def enable_debug_log(level: int):
@@ -315,50 +297,39 @@ class Core:
315
297
  def get_org_id_slug() -> (str, str):
316
298
  """
317
299
  Gets the Org ID and Org Slug for the API Token
318
- :return: Tuple of Org ID and Org Slug
300
+ :return:
319
301
  """
302
+ path = "organizations"
303
+ response = do_request(path)
304
+ data = response.json()
305
+ organizations = data.get("organizations")
320
306
  new_org_id = None
321
307
  new_org_slug = None
322
-
323
- sdk = Core.get_sdk()
324
- data = sdk.org.get()
325
- organizations = data.get("organizations")
326
-
327
308
  if len(organizations) == 1:
328
309
  for key in organizations:
329
310
  new_org_id = key
330
311
  new_org_slug = organizations[key].get('slug')
331
-
332
312
  return new_org_id, new_org_slug
333
313
 
334
314
  @staticmethod
335
- def get_sbom_data(full_scan_id: str) -> dict:
336
- sdk = Core.get_sdk()
337
- response_dict = sdk.fullscans.stream(org_slug, full_scan_id)
338
-
339
- if not response_dict.get("success"):
340
- results = []
341
- data = response_dict.get("message")
315
+ def get_sbom_data(full_scan_id: str) -> list:
316
+ path = f"orgs/{org_slug}/full-scans/{full_scan_id}"
317
+ response = do_request(path)
318
+ results = []
319
+ try:
320
+ data = response.json()
321
+ results = data.get("sbom_artifacts") or []
322
+ except Exception as error:
323
+ log.debug("Failed with old style full-scan API using new format")
324
+ log.debug(error)
325
+ data = response.text
342
326
  data.strip('"')
343
327
  data.strip()
344
-
345
328
  for line in data.split("\n"):
346
329
  if line != '"' and line != "" and line is not None:
347
330
  item = json.loads(line)
348
331
  results.append(item)
349
-
350
- return results
351
-
352
- keys_to_remove = ["success", "status"]
353
- for key in keys_to_remove:
354
- response_dict.pop(key, None)
355
-
356
- for key in response_dict:
357
- value = response_dict.get(key)
358
- response_dict[key] = Package(**value)
359
-
360
- return response_dict
361
-
332
+ return results
362
333
 
363
334
  @staticmethod
364
335
  def get_security_policy() -> dict:
@@ -366,21 +337,23 @@ class Core:
366
337
  Get the Security policy and determine the effective Org security policy
367
338
  :return:
368
339
  """
369
-
370
- sdk = Core.get_sdk()
371
- data = sdk.settings.get(org_id)
372
-
340
+ path = "settings"
341
+ payload = [
342
+ {
343
+ "organization": org_id
344
+ }
345
+ ]
346
+ response = do_request(path, payload=json.dumps(payload), method="POST")
347
+ data = response.json()
373
348
  defaults = data.get("defaults")
374
349
  default_rules = defaults.get("issueRules")
375
350
  entries = data.get("entries")
376
351
  org_rules = {}
377
-
378
352
  for org_set in entries:
379
353
  settings = org_set.get("settings")
380
354
  if settings is not None:
381
355
  org_details = settings.get("organization")
382
356
  org_rules = org_details.get("issueRules")
383
-
384
357
  for default in default_rules:
385
358
  if default not in org_rules:
386
359
  action = default_rules[default]["action"]
@@ -389,6 +362,10 @@ class Core:
389
362
  }
390
363
  return org_rules
391
364
 
365
+ # @staticmethod
366
+ # def get_supported_file_types() -> dict:
367
+ # path = "report/supported"
368
+
392
369
  @staticmethod
393
370
  def get_manifest_files(package: Package, packages: dict) -> str:
394
371
  if package.direct:
@@ -411,16 +388,15 @@ class Core:
411
388
 
412
389
  @staticmethod
413
390
  def create_sbom_output(diff: Diff) -> dict:
414
- sdk = Core.get_sdk()
415
- sbom = sdk.export.cdx_bom(org_slug, diff.id)
416
-
417
- if not sbom.get("success"):
391
+ base_path = f"orgs/{org_slug}/export/cdx"
392
+ path = f"{base_path}/{diff.id}"
393
+ result = do_request(path=path)
394
+ try:
395
+ sbom = result.json()
396
+ except Exception as error:
418
397
  log.error(f"Unable to get CycloneDX Output for {diff.id}")
419
- log.error(sbom.get("message"))
420
- return {}
421
-
422
- sbom.pop("success", None)
423
-
398
+ log.error(error)
399
+ sbom = {}
424
400
  return sbom
425
401
 
426
402
  @staticmethod
@@ -431,7 +407,7 @@ class Core:
431
407
  patterns = socket_globs[ecosystem]
432
408
  for file_name in patterns:
433
409
  pattern = patterns[file_name]["pattern"]
434
-
410
+ # path_pattern = f"**/{pattern}"
435
411
  for file in files:
436
412
  if "\\" in file:
437
413
  file = file.replace("\\", "/")
@@ -449,12 +425,11 @@ class Core:
449
425
  :param path: Str - path to where the manifest files are located
450
426
  :return:
451
427
  """
452
-
428
+ log.debug("Starting Find Files")
453
429
  start_time = time.time()
454
430
  files = set()
455
431
  for ecosystem in socket_globs:
456
432
  patterns = socket_globs[ecosystem]
457
-
458
433
  for file_name in patterns:
459
434
  pattern = patterns[file_name]["pattern"]
460
435
  file_path = f"{path}/**/{pattern}"
@@ -462,15 +437,14 @@ class Core:
462
437
  log.debug(f"Globbing {file_path}")
463
438
  glob_start = time.time()
464
439
  glob_files = glob(file_path, recursive=True)
465
-
466
440
  for glob_file in glob_files:
467
441
  if glob_file not in files:
468
442
  files.add(glob_file)
469
-
470
443
  glob_end = time.time()
471
444
  glob_total_time = glob_end - glob_start
472
445
  log.debug(f"Glob for pattern {file_path} took {glob_total_time:.2f} seconds")
473
446
 
447
+ log.debug("Finished Find Files")
474
448
  end_time = time.time()
475
449
  total_time = end_time - start_time
476
450
  log.info(f"Found {len(files)} in {total_time:.2f} seconds")
@@ -487,7 +461,7 @@ class Core:
487
461
  """
488
462
  send_files = []
489
463
  create_full_start = time.time()
490
-
464
+ log.debug("Creating new full scan")
491
465
  for file in files:
492
466
  if platform.system() == "Windows":
493
467
  file = file.replace("\\", "/")
@@ -511,12 +485,10 @@ class Core:
511
485
  )
512
486
  )
513
487
  send_files.append(payload)
514
-
515
- sdk = Core.get_sdk()
516
- params_dict = params.__dict__
517
- params_dict["org_slug"] = org_slug
518
- results = sdk.fullscans.post(files=files, params=params_dict)
519
-
488
+ query_params = urlencode(params.__dict__)
489
+ full_uri = f"{full_scan_path}?{query_params}"
490
+ response = do_request(full_uri, method="POST", files=send_files)
491
+ results = response.json()
520
492
  full_scan = FullScan(**results)
521
493
  full_scan.sbom_artifacts = Core.get_sbom_data(full_scan.id)
522
494
  create_full_end = time.time()
@@ -541,13 +513,26 @@ class Core:
541
513
  :param repo_slug: Str - Repo slug for the repository that is being diffed
542
514
  :return:
543
515
  """
544
-
545
- sdk = Core.get_sdk()
546
- results = sdk.repos.repo(org_slug, repo_slug)
516
+ repo_path = f"{repository_path}/{repo_slug}"
517
+ response = do_request(repo_path)
518
+ results = response.json()
547
519
  repository = Repository(**results)
548
-
549
520
  return repository.head_full_scan_id
550
521
 
522
+ @staticmethod
523
+ def get_full_scan(full_scan_id: str) -> FullScan:
524
+ """
525
+ Get the specified full scan and return a FullScan object
526
+ :param full_scan_id: str - ID of the full scan to pull
527
+ :return:
528
+ """
529
+ full_scan_url = f"{full_scan_path}/{full_scan_id}"
530
+ response = do_request(full_scan_url)
531
+ results = response.json()
532
+ full_scan = FullScan(**results)
533
+ full_scan.sbom_artifacts = Core.get_sbom_data(full_scan.id)
534
+ return full_scan
535
+
551
536
  @staticmethod
552
537
  def create_new_diff(
553
538
  path: str,
@@ -570,13 +555,11 @@ class Core:
570
555
  diff = Diff()
571
556
  diff.id = "no_diff_id"
572
557
  return diff
573
-
574
558
  files = Core.find_files(path)
575
559
  if files is None or len(files) == 0:
576
560
  diff = Diff()
577
561
  diff.id = "no_diff_id"
578
562
  return diff
579
-
580
563
  try:
581
564
  head_full_scan_id = Core.get_head_scan_for_repo(params.repo)
582
565
  if head_full_scan_id is None or head_full_scan_id == "":
@@ -587,35 +570,29 @@ class Core:
587
570
  head_end = time.time()
588
571
  total_head_time = head_end - head_start
589
572
  log.info(f"Total time to get head full-scan {total_head_time: .2f}")
590
-
591
573
  except APIResourceNotFound:
592
574
  head_full_scan_id = None
593
575
  head_full_scan = []
594
-
595
576
  new_scan_start = time.time()
596
577
  new_full_scan = Core.create_full_scan(files, params, workspace)
597
- new_full_scan.packages = new_full_scan.sbom_artifacts
578
+ new_full_scan.packages = Core.create_sbom_dict(new_full_scan.sbom_artifacts)
598
579
  new_scan_end = time.time()
599
-
600
580
  total_new_time = new_scan_end - new_scan_start
601
581
  log.info(f"Total time to get new full-scan {total_new_time: .2f}")
602
-
603
582
  diff_report = Core.compare_sboms(new_full_scan.sbom_artifacts, head_full_scan)
604
583
  diff_report.packages = new_full_scan.packages
605
-
584
+ # Set the diff ID and URLs
606
585
  base_socket = "https://socket.dev/dashboard/org"
607
586
  diff_report.id = new_full_scan.id
608
587
  diff_report.report_url = f"{base_socket}/{org_slug}/sbom/{diff_report.id}"
609
-
610
588
  if head_full_scan_id is not None:
611
589
  diff_report.diff_url = f"{base_socket}/{org_slug}/diff/{diff_report.id}/{head_full_scan_id}"
612
590
  else:
613
591
  diff_report.diff_url = diff_report.report_url
614
-
615
592
  return diff_report
616
593
 
617
594
  @staticmethod
618
- def compare_sboms(new_scan: dict, head_scan: dict) -> Diff:
595
+ def compare_sboms(new_scan: list, head_scan: list) -> Diff:
619
596
  """
620
597
  compare the SBOMs of the new full Scan and the head full scan. Return a Diff report with new packages,
621
598
  removed packages, and new alerts for the new full scan compared to the head.
@@ -623,33 +600,28 @@ class Core:
623
600
  :param head_scan: FullScan - Current head FullScan for the repository
624
601
  :return:
625
602
  """
626
- diff: Diff = Diff()
627
- new_packages = new_scan
628
- head_packages = head_scan
629
-
603
+ diff: Diff
604
+ diff = Diff()
605
+ new_packages = Core.create_sbom_dict(new_scan)
606
+ head_packages = Core.create_sbom_dict(head_scan)
630
607
  new_scan_alerts = {}
631
608
  head_scan_alerts = {}
632
609
  consolidated = set()
633
-
634
610
  for package_id in new_packages:
635
611
  purl, package = Core.create_purl(package_id, new_packages)
636
612
  base_purl = f"{purl.ecosystem}/{purl.name}@{purl.version}"
637
-
638
613
  if package_id not in head_packages and package.direct and base_purl not in consolidated:
639
614
  diff.new_packages.append(purl)
640
615
  consolidated.add(base_purl)
641
616
  new_scan_alerts = Core.create_issue_alerts(package, new_scan_alerts, new_packages)
642
-
643
617
  for package_id in head_packages:
644
618
  purl, package = Core.create_purl(package_id, head_packages)
645
619
  if package_id not in new_packages and package.direct:
646
620
  diff.removed_packages.append(purl)
647
621
  head_scan_alerts = Core.create_issue_alerts(package, head_scan_alerts, head_packages)
648
-
649
622
  diff.new_alerts = Core.compare_issue_alerts(new_scan_alerts, head_scan_alerts, diff.new_alerts)
650
623
  diff.new_capabilities = Core.compare_capabilities(new_packages, head_packages)
651
624
  diff = Core.add_capabilities_to_purl(diff)
652
-
653
625
  return diff
654
626
 
655
627
  @staticmethod
@@ -855,6 +827,32 @@ class Core:
855
827
  )
856
828
  return purl, package
857
829
 
830
+ @staticmethod
831
+ def create_sbom_dict(sbom: list) -> dict:
832
+ """
833
+ Converts the SBOM Artifacts from the FulLScan into a Dictionary for parsing
834
+ :param sbom: list - Raw artifacts for the SBOM
835
+ :return:
836
+ """
837
+ packages = {}
838
+ top_level_count = {}
839
+ for item in sbom:
840
+ package = Package(**item)
841
+ if package.id in packages:
842
+ print("Duplicate package?")
843
+ else:
844
+ package = Core.get_license_details(package)
845
+ packages[package.id] = package
846
+ for top_id in package.topLevelAncestors:
847
+ if top_id not in top_level_count:
848
+ top_level_count[top_id] = 1
849
+ else:
850
+ top_level_count[top_id] += 1
851
+ if len(top_level_count) > 0:
852
+ for package_id in top_level_count:
853
+ packages[package_id].transitives = top_level_count[package_id]
854
+ return packages
855
+
858
856
  @staticmethod
859
857
  def save_file(file_name: str, content: str) -> None:
860
858
  file = open(file_name, "w")
@@ -1,29 +1,30 @@
1
1
  import json
2
2
  import os
3
3
  from socketsecurity.core import log, do_request
4
+ import requests
4
5
  from socketsecurity.core.classes import Comment
5
6
  from socketsecurity.core.scm_comments import Comments
6
7
  import sys
7
8
 
8
9
 
9
- github_sha = None
10
- github_api_url = None
11
- github_ref_type = None
12
- github_event_name = None
13
- github_workspace = None
14
- github_repository = None
15
- github_ref_name = None
16
- github_actor = None
17
- default_branch = None
18
- github_env = None
19
- pr_number = None
20
- pr_name = None
21
- is_default_branch = False
22
- commit_message = None
23
- committer = None
24
- gh_api_token = None
25
- github_repository_owner = None
26
- event_action = None
10
+ global github_sha
11
+ global github_api_url
12
+ global github_ref_type
13
+ global github_event_name
14
+ global github_workspace
15
+ global github_repository
16
+ global github_ref_name
17
+ global github_actor
18
+ global default_branch
19
+ global github_env
20
+ global pr_number
21
+ global pr_name
22
+ global is_default_branch
23
+ global commit_message
24
+ global committer
25
+ global gh_api_token
26
+ global github_repository_owner
27
+ global event_action
27
28
 
28
29
  github_variables = [
29
30
  "GITHUB_SHA",
@@ -46,14 +47,16 @@ github_variables = [
46
47
 
47
48
  for env in github_variables:
48
49
  var_name = env.lower()
49
- value = os.getenv(env)
50
- globals()[var_name] = value
51
-
50
+ globals()[var_name] = os.getenv(env) or None
52
51
  if var_name == "default_branch":
53
- is_default_branch = bool(value and value.lower() != "false")
54
-
55
- if var_name != "gh_api_token":
56
- log.debug(f"{env}={value}")
52
+ global is_default_branch
53
+ if default_branch is None or default_branch.lower() == "false":
54
+ is_default_branch = False
55
+ else:
56
+ is_default_branch = True
57
+ if var_name != "gh_api_token":
58
+ value = globals()[var_name] = os.getenv(env) or None
59
+ log.debug(f"{env}={value}")
57
60
 
58
61
  headers = {
59
62
  'Authorization': f"Bearer {gh_api_token}",
@@ -167,15 +167,12 @@ def output_console_comments(diff_report: Diff, sbom_file_name: str = None) -> No
167
167
  console_security_comment = Messages.create_console_security_alert_table(diff_report)
168
168
  save_sbom_file(diff_report, sbom_file_name)
169
169
  log.info(f"Socket Full Scan ID: {diff_report.id}")
170
-
171
170
  if len(diff_report.new_alerts) > 0:
172
171
  log.info("Security issues detected by Socket Security")
173
172
  msg = f"\n{console_security_comment}"
174
173
  log.info(msg)
175
-
176
174
  if not report_pass(diff_report) and not blocking_disabled:
177
175
  sys.exit(1)
178
-
179
176
  else:
180
177
  # Means only warning alerts with no blocked
181
178
  if not blocking_disabled:
@@ -191,7 +188,7 @@ def output_console_json(diff_report: Diff, sbom_file_name: str = None) -> None:
191
188
  print(json.dumps(console_security_comment))
192
189
  if not report_pass(diff_report) and not blocking_disabled:
193
190
  sys.exit(1)
194
- if len(diff_report.new_alerts) > 0 and not blocking_disabled:
191
+ elif len(diff_report.new_alerts) > 0 and not blocking_disabled:
195
192
  # Means only warning alerts with no blocked
196
193
  sys.exit(5)
197
194
 
@@ -255,7 +252,6 @@ def main_code():
255
252
  ignore_commit_files = arguments.ignore_commit_files
256
253
  disable_blocking = arguments.disable_blocking
257
254
  allow_unverified = arguments.allow_unverified
258
-
259
255
  if disable_blocking:
260
256
  global blocking_disabled
261
257
  blocking_disabled = True
@@ -312,20 +308,13 @@ def main_code():
312
308
  default_branch = scm.is_default_branch
313
309
 
314
310
  base_api_url = os.getenv("BASE_API_URL") or None
315
-
316
- Core.initialize(
317
- token=api_token,
318
- request_timeout=1200,
319
- base_api_url=base_api_url,
320
- allow_unverified=allow_unverified
321
- )
322
-
311
+ core = Core(token=api_token, request_timeout=1200, base_api_url=base_api_url, allow_unverified=allow_unverified)
323
312
  no_change = True
324
313
  if ignore_commit_files:
325
314
  no_change = False
326
315
  elif is_repo and files is not None and len(files) > 0:
327
316
  log.info(files)
328
- no_change = Core.match_supported_files(files)
317
+ no_change = core.match_supported_files(files)
329
318
 
330
319
  set_as_pending_head = False
331
320
  if default_branch:
@@ -355,7 +344,7 @@ def main_code():
355
344
  log.info("No manifest files changes, skipping scan")
356
345
  # log.info("No dependency changes")
357
346
  elif scm.check_event_type() == "diff":
358
- diff = Core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
347
+ diff = core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
359
348
  log.info("Starting comment logic for PR/MR event")
360
349
  log.debug(f"Getting comments for Repo {scm.repository} for PR {scm.pr_number}")
361
350
  comments = scm.get_comments_for_pr(repo, str(pr_number))
@@ -399,7 +388,7 @@ def main_code():
399
388
  )
400
389
  else:
401
390
  log.info("Starting non-PR/MR flow")
402
- diff = Core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
391
+ diff = core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
403
392
  if enable_json:
404
393
  log.debug("Outputting JSON Results")
405
394
  output_console_json(diff, sbom_file)
@@ -408,7 +397,7 @@ def main_code():
408
397
  else:
409
398
  log.info("API Mode")
410
399
  diff: Diff
411
- diff = Core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
400
+ diff = core.create_new_diff(target_path, params, workspace=target_path, no_change=no_change)
412
401
  if enable_json:
413
402
  output_console_json(diff, sbom_file)
414
403
  else:
@@ -429,7 +418,7 @@ def main_code():
429
418
  "license_text": package.license_text
430
419
  }
431
420
  all_packages[package_id] = output
432
- Core.save_file(license_file, json.dumps(all_packages))
421
+ core.save_file(license_file, json.dumps(all_packages))
433
422
 
434
423
 
435
424
  if __name__ == '__main__':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: socketsecurity
3
- Version: 1.0.34
3
+ Version: 1.0.35
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Author-email: Douglas Coburn <douglas@socket.dev>
6
6
  Maintainer-email: Douglas Coburn <douglas@socket.dev>
@@ -15,16 +15,12 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Requires-Python: >=3.9
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: requests>=2.32.0
19
- Requires-Dist: mdutils~=1.6.0
18
+ Requires-Dist: requests
19
+ Requires-Dist: mdutils
20
20
  Requires-Dist: prettytable
21
21
  Requires-Dist: argparse
22
- Requires-Dist: GitPython>=3.1.43
23
- Requires-Dist: packaging>=24.1
24
- Requires-Dist: python-dotenv>=1.0.1
25
- Requires-Dist: socket-sdk-python>=1.0.14
26
- Provides-Extra: dev
27
- Requires-Dist: ruff>=0.3.0; extra == "dev"
22
+ Requires-Dist: GitPython
23
+ Requires-Dist: packaging
28
24
 
29
25
  # Socket Security CLI
30
26
 
@@ -0,0 +1,6 @@
1
+ requests
2
+ mdutils
3
+ prettytable
4
+ argparse
5
+ GitPython
6
+ packaging
@@ -1,130 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools >= 61.0"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "socketsecurity"
7
- dynamic = ["version"]
8
- requires-python = ">= 3.9"
9
- dependencies = [
10
- 'requests >= 2.32.0',
11
- 'mdutils ~= 1.6.0',
12
- 'prettytable',
13
- 'argparse',
14
- 'GitPython >= 3.1.43',
15
- 'packaging >= 24.1',
16
- 'python-dotenv >= 1.0.1',
17
- 'socket-sdk-python >= 1.0.14'
18
- ]
19
-
20
-
21
- readme = "README.md"
22
- description = "Socket Security CLI for CI/CD"
23
- keywords = ["socketsecurity", "socket.dev", "sca", "oss", "security"]
24
- authors = [
25
- {name = "Douglas Coburn", email = "douglas@socket.dev"}
26
- ]
27
- maintainers = [
28
- {name = "Douglas Coburn", email = "douglas@socket.dev"}
29
- ]
30
- classifiers = [
31
- "Development Status :: 4 - Beta",
32
- "Intended Audience :: Developers",
33
- "Programming Language :: Python :: 3.9",
34
- "Programming Language :: Python :: 3.10",
35
- "Programming Language :: Python :: 3.11",
36
- "Programming Language :: Python :: 3.12",
37
- ]
38
-
39
- # modern, faster linter and language server. install with `pip install -e ".[dev]"`
40
- [project.optional-dependencies]
41
- dev = [
42
- "ruff>=0.3.0",
43
- ]
44
-
45
- [project.scripts]
46
- socketcli = "socketsecurity.socketcli:cli"
47
-
48
- [project.urls]
49
- Homepage = "https://socket.dev"
50
-
51
- [tool.setuptools.packages.find]
52
- include = [
53
- "socketsecurity",
54
- "socketsecurity.core"
55
- ]
56
-
57
- [tool.setuptools.dynamic]
58
- version = {attr = "socketsecurity.__version__"}
59
-
60
- [tool.ruff]
61
- # Exclude a variety of commonly ignored directories.
62
- exclude = [
63
- ".bzr",
64
- ".direnv",
65
- ".eggs",
66
- ".git",
67
- ".git-rewrite",
68
- ".hg",
69
- ".ipynb_checkpoints",
70
- ".mypy_cache",
71
- ".nox",
72
- ".pants.d",
73
- ".pyenv",
74
- ".pytest_cache",
75
- ".pytype",
76
- ".ruff_cache",
77
- ".svn",
78
- ".tox",
79
- ".venv",
80
- ".vscode",
81
- "__pypackages__",
82
- "_build",
83
- "buck-out",
84
- "build",
85
- "dist",
86
- "node_modules",
87
- "site-packages",
88
- "venv",
89
- ]
90
-
91
- [tool.ruff.lint]
92
- # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
93
- # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
94
- # McCabe complexity (`C901`) by default.
95
- select = ["E4", "E7", "E9", "F"]
96
- ignore = []
97
-
98
- # Allow fix for all enabled rules (when `--fix`) is provided.
99
- fixable = ["ALL"]
100
- unfixable = []
101
-
102
- # Allow unused variables when underscore-prefixed.
103
- dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
104
-
105
- [tool.ruff.format]
106
- # Like Black, use double quotes for strings.
107
- quote-style = "double"
108
-
109
- # Like Black, indent with spaces, rather than tabs.
110
- indent-style = "space"
111
-
112
- # Like Black, respect magic trailing commas.
113
- skip-magic-trailing-comma = false
114
-
115
- # Like Black, automatically detect the appropriate line ending.
116
- line-ending = "auto"
117
-
118
- # Enable auto-formatting of code examples in docstrings. Markdown,
119
- # reStructuredText code/literal blocks and doctests are all supported.
120
- #
121
- # This is currently disabled by default, but it is planned for this
122
- # to be opt-out in the future.
123
- docstring-code-format = false
124
-
125
- # Set the line length limit used when formatting code snippets in
126
- # docstrings.
127
- #
128
- # This only has an effect when the `docstring-code-format` setting is
129
- # enabled.
130
- docstring-code-line-length = "dynamic"
@@ -1,11 +0,0 @@
1
- requests>=2.32.0
2
- mdutils~=1.6.0
3
- prettytable
4
- argparse
5
- GitPython>=3.1.43
6
- packaging>=24.1
7
- python-dotenv>=1.0.1
8
- socket-sdk-python>=1.0.14
9
-
10
- [dev]
11
- ruff>=0.3.0
File without changes