cycode 0.2.3__tar.gz → 0.2.4.dev10__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 (85) hide show
  1. {cycode-0.2.3 → cycode-0.2.4.dev10}/PKG-INFO +30 -4
  2. cycode-0.2.4.dev10/cycode/__init__.py +1 -0
  3. cycode-0.2.4.dev10/cycode/cli/auth/auth_command.py +79 -0
  4. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/auth/auth_manager.py +9 -7
  5. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/code_scanner.py +84 -40
  6. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/config.py +4 -2
  7. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/exceptions/custom_exceptions.py +15 -6
  8. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/helpers/maven/base_restore_maven_dependencies.py +4 -4
  9. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/helpers/maven/restore_gradle_dependencies.py +2 -2
  10. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/helpers/maven/restore_maven_dependencies.py +3 -3
  11. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/helpers/sca_code_scanner.py +6 -6
  12. cycode-0.2.3/cli/cycode.py → cycode-0.2.4.dev10/cycode/cli/main.py +26 -15
  13. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/models.py +1 -1
  14. cycode-0.2.4.dev10/cycode/cli/printers/__init__.py +10 -0
  15. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/printers/base_printer.py +4 -2
  16. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/printers/json_printer.py +3 -3
  17. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/printers/results_printer.py +4 -4
  18. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/printers/table_printer.py +15 -9
  19. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/printers/text_printer.py +8 -6
  20. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/user_settings/base_file_manager.py +1 -1
  21. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/user_settings/config_file_manager.py +3 -2
  22. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/user_settings/configuration_manager.py +3 -2
  23. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/user_settings/credentials_manager.py +4 -3
  24. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/user_settings/user_settings_commands.py +9 -8
  25. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/shell_executor.py +1 -1
  26. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/string_utils.py +1 -0
  27. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/__init__.py +0 -3
  28. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/auth_client.py +12 -16
  29. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/config.py +3 -3
  30. cycode-0.2.4.dev10/cycode/cyclient/cycode_client.py +8 -0
  31. cycode-0.2.4.dev10/cycode/cyclient/cycode_client_base.py +86 -0
  32. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/cycode_dev_based_client.py +2 -2
  33. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/cycode_token_based_client.py +18 -18
  34. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/models.py +10 -8
  35. cycode-0.2.4.dev10/cycode/cyclient/scan_client.py +122 -0
  36. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/scan_config/scan_config_creator.py +6 -6
  37. cycode-0.2.4.dev10/pyproject.toml +61 -0
  38. cycode-0.2.3/LICENCE +0 -21
  39. cycode-0.2.3/VERSION.txt +0 -1
  40. cycode-0.2.3/cli/__init__.py +0 -1
  41. cycode-0.2.3/cli/auth/auth_command.py +0 -34
  42. cycode-0.2.3/cli/printers/__init__.py +0 -10
  43. cycode-0.2.3/cyclient/cycode_client.py +0 -14
  44. cycode-0.2.3/cyclient/cycode_client_base.py +0 -67
  45. cycode-0.2.3/cyclient/scan_client.py +0 -161
  46. cycode-0.2.3/cycode.egg-info/PKG-INFO +0 -718
  47. cycode-0.2.3/cycode.egg-info/SOURCES.txt +0 -76
  48. cycode-0.2.3/cycode.egg-info/dependency_links.txt +0 -1
  49. cycode-0.2.3/cycode.egg-info/entry_points.txt +0 -2
  50. cycode-0.2.3/cycode.egg-info/requires.txt +0 -12
  51. cycode-0.2.3/cycode.egg-info/top_level.txt +0 -3
  52. cycode-0.2.3/cycode.egg-info/zip-safe +0 -1
  53. cycode-0.2.3/setup.cfg +0 -4
  54. cycode-0.2.3/setup.py +0 -50
  55. cycode-0.2.3/tests/__init__.py +0 -34
  56. cycode-0.2.3/tests/cyclient/test_scan_client.py +0 -10
  57. cycode-0.2.3/tests/test_code_scanner.py +0 -10
  58. cycode-0.2.3/tests/test_models.py +0 -25
  59. cycode-0.2.3/tests/test_zip_file.py +0 -9
  60. cycode-0.2.3/tests/user_settings/__init__.py +0 -0
  61. cycode-0.2.3/tests/user_settings/test_configuration_manager.py +0 -74
  62. cycode-0.2.3/tests/user_settings/test_user_settings_commands.py +0 -103
  63. cycode-0.2.3/tests/utils/__init__.py +0 -0
  64. cycode-0.2.3/tests/utils/test_path_utils.py +0 -36
  65. {cycode-0.2.3 → cycode-0.2.4.dev10}/README.md +0 -0
  66. {cycode-0.2.3/cli/auth → cycode-0.2.4.dev10/cycode/cli}/__init__.py +0 -0
  67. {cycode-0.2.3/cli/exceptions → cycode-0.2.4.dev10/cycode/cli/auth}/__init__.py +0 -0
  68. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/ci_integrations.py +0 -0
  69. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/config.yaml +0 -0
  70. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/consts.py +0 -0
  71. {cycode-0.2.3/cli/helpers → cycode-0.2.4.dev10/cycode/cli/exceptions}/__init__.py +0 -0
  72. {cycode-0.2.3/cli/helpers/maven → cycode-0.2.4.dev10/cycode/cli/helpers}/__init__.py +0 -0
  73. {cycode-0.2.3/cli/user_settings → cycode-0.2.4.dev10/cycode/cli/helpers/maven}/__init__.py +0 -0
  74. {cycode-0.2.3/cli/utils → cycode-0.2.4.dev10/cycode/cli/user_settings}/__init__.py +0 -0
  75. {cycode-0.2.3/cyclient/scan_config → cycode-0.2.4.dev10/cycode/cli/utils}/__init__.py +0 -0
  76. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/path_utils.py +0 -0
  77. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/scan_utils.py +0 -0
  78. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/task_timer.py +0 -0
  79. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/utils/yaml_utils.py +0 -0
  80. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cli/zip_file.py +0 -0
  81. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/config.yaml +0 -0
  82. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/config_dev.py +0 -0
  83. {cycode-0.2.3/tests/cyclient → cycode-0.2.4.dev10/cycode/cyclient/scan_config}/__init__.py +0 -0
  84. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/scan_config/scan_config_base.py +0 -0
  85. {cycode-0.2.3 → cycode-0.2.4.dev10/cycode}/cyclient/utils.py +0 -0
@@ -1,19 +1,45 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cycode
3
- Version: 0.2.3
3
+ Version: 0.2.4.dev10
4
4
  Summary: Perform secrets/iac scans for your sources using Cycode's engine
5
5
  Home-page: https://github.com/cycodehq-public/cycode-cli
6
+ License: MIT
7
+ Keywords: secret-scan,cycode,devops,token,secret,security,cycode,code
6
8
  Author: Cycode
7
9
  Author-email: support@cycode.com
8
- License: MIT
9
- Keywords: secret-scan cycode devops token secret security cycode code
10
+ Requires-Python: >=3.7,<4.0
11
+ Classifier: Development Status :: 5 - Production/Stable
10
12
  Classifier: Environment :: Console
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: OS Independent
11
16
  Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.7
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3 :: Only
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
12
26
  Classifier: Programming Language :: Python :: 3.7
13
27
  Classifier: Programming Language :: Python :: 3.8
14
28
  Classifier: Programming Language :: Python :: 3.9
29
+ Requires-Dist: arrow (>=0.17.0,<0.18.0)
30
+ Requires-Dist: binaryornot (>=0.4.4,<0.5.0)
31
+ Requires-Dist: click (>=8.1.0,<8.2.0)
32
+ Requires-Dist: colorama (>=0.4.3,<0.5.0)
33
+ Requires-Dist: gitpython (>=3.1.30,<3.2.0)
34
+ Requires-Dist: halo (==0.0.31)
35
+ Requires-Dist: marshmallow (>=3.8.0,<3.9.0)
36
+ Requires-Dist: pathspec (>=0.8.0,<0.9.0)
37
+ Requires-Dist: pyyaml (>=6.0,<7.0)
38
+ Requires-Dist: requests (>=2.24,<3.0)
39
+ Requires-Dist: texttable (>=1.6.7,<1.7.0)
40
+ Requires-Dist: typing (>=3.7.4.3,<3.8.0.0)
41
+ Project-URL: Repository, https://github.com/cycodehq-public/cycode-cli
15
42
  Description-Content-Type: text/markdown
16
- License-File: LICENCE
17
43
 
18
44
  # Cycode CLI User Guide
19
45
 
@@ -0,0 +1 @@
1
+ __version__ = '0.2.4.dev10' # placeholder. Will be filled automatically on poetry build from Git Tag
@@ -0,0 +1,79 @@
1
+ import json
2
+
3
+ import click
4
+ import traceback
5
+
6
+ from cycode.cli.auth.auth_manager import AuthManager
7
+ from cycode.cli.user_settings.credentials_manager import CredentialsManager
8
+ from cycode.cli.exceptions.custom_exceptions import AuthProcessError, NetworkError, HttpUnauthorizedError
9
+ from cycode.cyclient import logger
10
+ from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
11
+
12
+
13
+ @click.group(invoke_without_command=True)
14
+ @click.pass_context
15
+ def authenticate(context: click.Context):
16
+ """ Authenticates your machine to associate CLI with your cycode account """
17
+ if context.invoked_subcommand is not None:
18
+ # if it is a subcommand do nothing
19
+ return
20
+
21
+ try:
22
+ logger.debug("starting authentication process")
23
+ auth_manager = AuthManager()
24
+ auth_manager.authenticate()
25
+ click.echo("Successfully logged into cycode")
26
+ except Exception as e:
27
+ _handle_exception(context, e)
28
+
29
+
30
+ @authenticate.command(name='check')
31
+ @click.pass_context
32
+ def authorization_check(context: click.Context):
33
+ """ Check your machine associating CLI with your cycode account """
34
+ passed_auth_check_args = {'context': context, 'content': {
35
+ 'success': True,
36
+ 'message': 'You are authorized'
37
+ }, 'color': 'green'}
38
+ failed_auth_check_args = {'context': context, 'content': {
39
+ 'success': False,
40
+ 'message': 'You are not authorized'
41
+ }, 'color': 'red'}
42
+
43
+ client_id, client_secret = CredentialsManager().get_credentials()
44
+ if not client_id or not client_secret:
45
+ return _print_result(**failed_auth_check_args)
46
+
47
+ try:
48
+ # TODO(MarshalX): This property performs HTTP request to refresh the token. This must be the method.
49
+ if CycodeTokenBasedClient(client_id, client_secret).api_token:
50
+ return _print_result(**passed_auth_check_args)
51
+ except (NetworkError, HttpUnauthorizedError):
52
+ if context.obj['verbose']:
53
+ click.secho(f'Error: {traceback.format_exc()}', fg='red', nl=False)
54
+
55
+ return _print_result(**failed_auth_check_args)
56
+
57
+
58
+ def _print_result(context: click.Context, content: dict, color: str) -> None:
59
+ # the current impl of printers supports only results of scans
60
+ if context.obj['output'] == 'text':
61
+ return click.secho(content['message'], fg=color)
62
+
63
+ return click.echo(json.dumps({'result': content['success'], 'message': content['message']}))
64
+
65
+
66
+ def _handle_exception(context: click.Context, e: Exception):
67
+ verbose = context.obj["verbose"]
68
+ if verbose:
69
+ click.secho(f'Error: {traceback.format_exc()}', fg='red', nl=False)
70
+ if isinstance(e, AuthProcessError):
71
+ click.secho('Authentication failed. Please try again later using the command `cycode auth`',
72
+ fg='red', nl=False)
73
+ elif isinstance(e, NetworkError):
74
+ click.secho('Authentication failed. Please try again later using the command `cycode auth`',
75
+ fg='red', nl=False)
76
+ elif isinstance(e, click.ClickException):
77
+ raise e
78
+ else:
79
+ raise click.ClickException(str(e))
@@ -2,13 +2,14 @@ import time
2
2
  import webbrowser
3
3
  from requests import Request
4
4
  from typing import Optional
5
- from cli.exceptions.custom_exceptions import AuthProcessError
6
- from cli.utils.string_utils import generate_random_string, hash_string_to_sha256
7
- from cli.user_settings.configuration_manager import ConfigurationManager
8
- from cli.user_settings.credentials_manager import CredentialsManager
9
- from cyclient.auth_client import AuthClient
10
- from cyclient.models import ApiToken, ApiTokenGenerationPollingResponse
11
- from cyclient import logger
5
+
6
+ from cycode.cli.exceptions.custom_exceptions import AuthProcessError
7
+ from cycode.cli.utils.string_utils import generate_random_string, hash_string_to_sha256
8
+ from cycode.cli.user_settings.configuration_manager import ConfigurationManager
9
+ from cycode.cli.user_settings.credentials_manager import CredentialsManager
10
+ from cycode.cyclient.auth_client import AuthClient
11
+ from cycode.cyclient.models import ApiToken, ApiTokenGenerationPollingResponse
12
+ from cycode.cyclient import logger
12
13
 
13
14
 
14
15
  class AuthManager:
@@ -84,6 +85,7 @@ class AuthManager:
84
85
  'code_challenge': code_challenge,
85
86
  'session_id': session_id
86
87
  }
88
+ # TODO(MarshalX). Use auth_client instead and don't depend on "requests" lib here
87
89
  request = Request(url=login_url, params=query_params)
88
90
  return request.prepare().url
89
91
 
@@ -1,3 +1,5 @@
1
+ from typing import Type, NamedTuple
2
+
1
3
  import click
2
4
  import json
3
5
  import logging
@@ -12,22 +14,22 @@ from sys import getsizeof
12
14
 
13
15
  from halo import Halo
14
16
 
15
- from cli.printers import ResultsPrinter
16
- from cli.models import Document, DocumentDetections, Severity
17
- from cli.ci_integrations import get_commit_range
18
- from cli.consts import *
19
- from cli.config import configuration_manager, config
20
- from cli.utils.path_utils import is_sub_path, is_binary_file, get_file_size, get_relevant_files_in_path, \
17
+ from cycode.cli.printers import ResultsPrinter
18
+ from cycode.cli.models import Document, DocumentDetections, Severity
19
+ from cycode.cli.ci_integrations import get_commit_range
20
+ from cycode.cli.consts import *
21
+ from cycode.cli.config import configuration_manager
22
+ from cycode.cli.utils.path_utils import is_sub_path, is_binary_file, get_file_size, get_relevant_files_in_path, \
21
23
  get_path_by_os, get_file_content
22
- from cli.utils.string_utils import get_content_size, is_binary_content
23
- from cli.utils.task_timer import TimeoutAfter
24
- from cli.utils import scan_utils
25
- from cli.user_settings.config_file_manager import ConfigFileManager
26
- from cli.zip_file import InMemoryZip
27
- from cli.exceptions.custom_exceptions import *
28
- from cyclient import logger
29
- from cyclient.models import *
30
- from cli.helpers import sca_code_scanner
24
+ from cycode.cli.utils.string_utils import get_content_size, is_binary_content
25
+ from cycode.cli.utils.task_timer import TimeoutAfter
26
+ from cycode.cli.utils import scan_utils
27
+ from cycode.cli.user_settings.config_file_manager import ConfigFileManager
28
+ from cycode.cli.zip_file import InMemoryZip
29
+ from cycode.cli.exceptions.custom_exceptions import *
30
+ from cycode.cli.helpers import sca_code_scanner
31
+ from cycode.cyclient import logger
32
+ from cycode.cyclient.models import *
31
33
 
32
34
  start_scan_time = time.time()
33
35
 
@@ -817,34 +819,76 @@ def _is_subpath_of_cycode_configuration_folder(filename: str) -> bool:
817
819
  or filename.endswith(ConfigFileManager.get_config_file_route())
818
820
 
819
821
 
822
+ class CliScanError(NamedTuple):
823
+ soft_fail: bool
824
+ code: str
825
+ message: str
826
+
827
+
828
+ CliScanErrors = Dict[Type[Exception], CliScanError]
829
+
830
+
820
831
  def _handle_exception(context: click.Context, e: Exception):
821
- context.obj["did_fail"] = True
822
- verbose = context.obj["verbose"]
823
- if verbose:
832
+ context.obj['did_fail'] = True
833
+
834
+ if context.obj['verbose']:
824
835
  click.secho(f'Error: {traceback.format_exc()}', fg='red', nl=False)
825
- if isinstance(e, (CycodeError, ScanAsyncError)):
826
- click.secho('Cycode was unable to complete this scan. Please try again by executing the `cycode scan` command',
827
- fg='red', nl=False)
828
- context.obj["soft_fail"] = True
829
- elif isinstance(e, HttpUnauthorizedError):
830
- click.secho('Unable to authenticate to Cycode, your token is either invalid or has expired. '
831
- 'Please re-generate your token and reconfigure it by running the `cycode configure` command',
832
- fg='red', nl=False)
833
- context.obj["soft_fail"] = True
834
- elif isinstance(e, ZipTooLargeError):
835
- click.secho('The path you attempted to scan exceeds the current maximum scanning size cap (10MB). '
836
- 'Please try ignoring irrelevant paths using the ‘cycode ignore --by-path’ '
837
- 'command and execute the scan again',
838
- fg='red', nl=False)
839
- context.obj["soft_fail"] = True
840
- elif isinstance(e, InvalidGitRepositoryError):
841
- click.secho('The path you supplied does not correlate to a git repository. Should you still wish to scan '
842
- 'this path, use: ‘cycode scan path <path>’',
843
- fg='red', nl=False)
844
- elif isinstance(e, click.ClickException):
836
+
837
+ # TODO(MarshalX): Create global CLI errors database and move this
838
+ errors: CliScanErrors = {
839
+ NetworkError: CliScanError(
840
+ soft_fail=True,
841
+ code='cycode_error',
842
+ message='Cycode was unable to complete this scan. '
843
+ 'Please try again by executing the `cycode scan` command'
844
+ ),
845
+ ScanAsyncError: CliScanError(
846
+ soft_fail=True,
847
+ code='scan_error',
848
+ message='Cycode was unable to complete this scan. '
849
+ 'Please try again by executing the `cycode scan` command'
850
+ ),
851
+ HttpUnauthorizedError: CliScanError(
852
+ soft_fail=True,
853
+ code='auth_error',
854
+ message='Unable to authenticate to Cycode, your token is either invalid or has expired. '
855
+ 'Please re-generate your token and reconfigure it by running the `cycode configure` command'
856
+ ),
857
+ ZipTooLargeError: CliScanError(
858
+ soft_fail=True,
859
+ code='zip_too_large_error',
860
+ message='The path you attempted to scan exceeds the current maximum scanning size cap (10MB). '
861
+ 'Please try ignoring irrelevant paths using the ‘cycode ignore --by-path’ command '
862
+ 'and execute the scan again'
863
+ ),
864
+ InvalidGitRepositoryError: CliScanError(
865
+ soft_fail=False,
866
+ code='invalid_git_error',
867
+ message='The path you supplied does not correlate to a git repository. '
868
+ 'Should you still wish to scan this path, use: ‘cycode scan path <path>’'
869
+ ),
870
+ }
871
+
872
+ if type(e) in errors:
873
+ error = errors[type(e)]
874
+
875
+ if error.soft_fail is True:
876
+ context.obj['soft_fail'] = True
877
+
878
+ return _print_error(context, error)
879
+
880
+ if isinstance(e, click.ClickException):
845
881
  raise e
846
- else:
847
- raise click.ClickException(str(e))
882
+
883
+ raise click.ClickException(str(e))
884
+
885
+
886
+ def _print_error(context: click.Context, error: CliScanError) -> None:
887
+ # TODO(MarshalX): Extend functionality of CLI printers and move this
888
+ if context.obj['output'] == 'text':
889
+ click.secho(error.message, fg='red', nl=False)
890
+ elif context.obj['output'] == 'json':
891
+ click.echo(json.dumps({'error': error.code, 'message': error.message}, ensure_ascii=False))
848
892
 
849
893
 
850
894
  def _report_scan_status(context: click.Context, scan_type: str, scan_id: str, scan_completed: bool,
@@ -1,6 +1,8 @@
1
1
  import os
2
- from cli.utils.yaml_utils import read_file
3
- from cli.user_settings.configuration_manager import ConfigurationManager
2
+
3
+ from cycode.cli.utils.yaml_utils import read_file
4
+ from cycode.cli.user_settings.configuration_manager import ConfigurationManager
5
+
4
6
 
5
7
  relative_path = os.path.dirname(__file__)
6
8
  config_file_path = os.path.join(relative_path, 'config.yaml')
@@ -1,7 +1,15 @@
1
+ from requests import Response
2
+
3
+
1
4
  class CycodeError(Exception):
2
- def __init__(self, status_code: int, error_message: str):
5
+ """Base class for all custom exceptions"""
6
+
7
+
8
+ class NetworkError(CycodeError):
9
+ def __init__(self, status_code: int, error_message: str, response: Response):
3
10
  self.status_code = status_code
4
11
  self.error_message = error_message
12
+ self.response = response
5
13
  super().__init__(self.error_message)
6
14
 
7
15
  def __str__(self):
@@ -9,7 +17,7 @@ class CycodeError(Exception):
9
17
  f'{self.error_message}'
10
18
 
11
19
 
12
- class ScanAsyncError(Exception):
20
+ class ScanAsyncError(CycodeError):
13
21
  def __init__(self, error_message: str):
14
22
  self.error_message = error_message
15
23
  super().__init__(self.error_message)
@@ -18,17 +26,18 @@ class ScanAsyncError(Exception):
18
26
  return f'error occurred during the scan. error message: {self.error_message}'
19
27
 
20
28
 
21
- class HttpUnauthorizedError(Exception):
22
- def __init__(self, error_message: str):
29
+ class HttpUnauthorizedError(CycodeError):
30
+ def __init__(self, error_message: str, response: Response):
23
31
  self.status_code = 401
24
32
  self.error_message = error_message
33
+ self.response = response
25
34
  super().__init__(self.error_message)
26
35
 
27
36
  def __str__(self):
28
37
  return 'Http Unauthorized Error'
29
38
 
30
39
 
31
- class ZipTooLargeError(Exception):
40
+ class ZipTooLargeError(CycodeError):
32
41
  def __init__(self, size_limit: int):
33
42
  self.size_limit = size_limit
34
43
  super().__init__()
@@ -37,7 +46,7 @@ class ZipTooLargeError(Exception):
37
46
  return f'The size of zip to scan is too large, size limit: {self.size_limit}'
38
47
 
39
48
 
40
- class AuthProcessError(Exception):
49
+ class AuthProcessError(CycodeError):
41
50
  def __init__(self, error_message: str):
42
51
  self.error_message = error_message
43
52
  super().__init__()
@@ -3,10 +3,10 @@ from typing import List, Optional, Dict
3
3
 
4
4
  import click
5
5
 
6
- from cli.models import Document
7
- from cli.utils.path_utils import join_paths, get_file_dir
8
- from cli.utils.shell_executor import shell
9
- from cyclient import logger
6
+ from cycode.cli.models import Document
7
+ from cycode.cli.utils.path_utils import join_paths, get_file_dir
8
+ from cycode.cli.utils.shell_executor import shell
9
+ from cycode.cyclient import logger
10
10
 
11
11
 
12
12
  def build_dep_tree_path(path: str, generated_file_name: str) -> str:
@@ -2,8 +2,8 @@ from typing import List
2
2
 
3
3
  import click
4
4
 
5
- from cli.helpers.maven.base_restore_maven_dependencies import BaseRestoreMavenDependencies
6
- from cli.models import Document
5
+ from cycode.cli.helpers.maven.base_restore_maven_dependencies import BaseRestoreMavenDependencies
6
+ from cycode.cli.models import Document
7
7
 
8
8
  BUILD_GRADLE_FILE_NAME = 'build.gradle'
9
9
  BUILD_GRADLE_KTS_FILE_NAME = 'build.gradle.kts'
@@ -3,10 +3,10 @@ from typing import List, Optional
3
3
 
4
4
  import click
5
5
 
6
- from cli.helpers.maven.base_restore_maven_dependencies import BaseRestoreMavenDependencies, build_dep_tree_path, \
6
+ from cycode.cli.helpers.maven.base_restore_maven_dependencies import BaseRestoreMavenDependencies, build_dep_tree_path, \
7
7
  execute_command
8
- from cli.models import Document
9
- from cli.utils.path_utils import get_file_dir, get_file_content, join_paths
8
+ from cycode.cli.models import Document
9
+ from cycode.cli.utils.path_utils import get_file_dir, get_file_content, join_paths
10
10
 
11
11
  BUILD_MAVEN_FILE_NAME = 'pom.xml'
12
12
  MAVEN_CYCLONE_DEP_TREE_FILE_NAME = 'bom.json'
@@ -4,12 +4,12 @@ from typing import List, Optional, Dict
4
4
  import click
5
5
  from git import Repo, GitCommandError
6
6
 
7
- from cli.consts import *
8
- from cli.helpers.maven.restore_gradle_dependencies import RestoreGradleDependencies
9
- from cli.helpers.maven.restore_maven_dependencies import RestoreMavenDependencies
10
- from cli.models import Document
11
- from cli.utils.path_utils import get_file_dir, join_paths, get_file_content
12
- from cyclient import logger
7
+ from cycode.cli.consts import *
8
+ from cycode.cli.helpers.maven.restore_gradle_dependencies import RestoreGradleDependencies
9
+ from cycode.cli.helpers.maven.restore_maven_dependencies import RestoreMavenDependencies
10
+ from cycode.cli.models import Document
11
+ from cycode.cli.utils.path_utils import get_file_dir, join_paths, get_file_content
12
+ from cycode.cyclient import logger
13
13
 
14
14
  BUILD_GRADLE_FILE_NAME = 'build.gradle'
15
15
  BUILD_GRADLE_KTS_FILE_NAME = 'build.gradle.kts'
@@ -5,17 +5,17 @@ import sys
5
5
 
6
6
  from typing import List
7
7
 
8
- from cli.models import Severity
9
- from cli.config import config
10
- from cli import code_scanner, __version__
11
- from cyclient import logger
12
- from cyclient.scan_client import ScanClient
13
- from cli.user_settings.credentials_manager import CredentialsManager
14
- from cli.user_settings.configuration_manager import ConfigurationManager
15
- from cli.user_settings.user_settings_commands import set_credentials, add_exclusions
16
- from cli.auth.auth_command import authenticate
17
- from cli.utils import scan_utils
18
- from cyclient.scan_config.scan_config_creator import create_scan_client
8
+ from cycode import __version__
9
+ from cycode.cli.models import Severity
10
+ from cycode.cli.config import config
11
+ from cycode.cli import code_scanner
12
+ from cycode.cli.user_settings.credentials_manager import CredentialsManager
13
+ from cycode.cli.user_settings.configuration_manager import ConfigurationManager
14
+ from cycode.cli.user_settings.user_settings_commands import set_credentials, add_exclusions
15
+ from cycode.cli.auth.auth_command import authenticate
16
+ from cycode.cli.utils import scan_utils
17
+ from cycode.cyclient import logger
18
+ from cycode.cyclient.scan_config.scan_config_creator import create_scan_client
19
19
 
20
20
  CONTEXT = dict()
21
21
  ISSUE_DETECTED_STATUS_CODE = 1
@@ -60,7 +60,7 @@ NO_ISSUES_STATUS_CODE = 0
60
60
  help='Run scan without failing, always return a non-error status code',
61
61
  type=bool,
62
62
  required=False)
63
- @click.option('--output', default='text',
63
+ @click.option('--output', default=None,
64
64
  help="""
65
65
  \b
66
66
  Specify the results output (text/json),
@@ -104,7 +104,9 @@ def code_scan(context: click.Context, scan_type, client_id, secret, show_secret,
104
104
  context.obj["soft_fail"] = config["soft_fail"]
105
105
 
106
106
  context.obj["scan_type"] = scan_type
107
- context.obj["output"] = output
107
+ if output is not None:
108
+ # save backward compatability with old style command
109
+ context.obj["output"] = output
108
110
  context.obj["client"] = get_cycode_client(client_id, secret)
109
111
  context.obj["severity_threshold"] = severity_threshold
110
112
  context.obj["monitor"] = monitor
@@ -135,16 +137,25 @@ def finalize(context: click.Context, *args, **kwargs):
135
137
  @click.option(
136
138
  "--verbose", "-v", is_flag=True, default=False, help="Show detailed logs",
137
139
  )
140
+ @click.option(
141
+ '--output',
142
+ default='text',
143
+ help='Specify the output (text/json), the default is text',
144
+ type=click.Choice(['text', 'json'])
145
+ )
138
146
  @click.version_option(__version__, prog_name="cycode")
139
147
  @click.pass_context
140
- def main_cli(context: click.Context, verbose: bool):
148
+ def main_cli(context: click.Context, verbose: bool, output: str):
141
149
  context.ensure_object(dict)
142
150
  configuration_manager = ConfigurationManager()
151
+
143
152
  verbose = verbose or configuration_manager.get_verbose_flag()
144
- context.obj["verbose"] = verbose
153
+ context.obj['verbose'] = verbose
145
154
  log_level = logging.DEBUG if verbose else logging.INFO
146
155
  logger.setLevel(log_level)
147
156
 
157
+ context.obj['output'] = output
158
+
148
159
 
149
160
  def get_cycode_client(client_id, client_secret):
150
161
  if not client_id or not client_secret:
@@ -1,6 +1,6 @@
1
1
  from enum import Enum
2
2
  from typing import List
3
- from cyclient.models import Detection
3
+ from cycode.cyclient.models import Detection
4
4
 
5
5
 
6
6
  class Document:
@@ -0,0 +1,10 @@
1
+ from .json_printer import JsonPrinter
2
+ from .text_printer import TextPrinter
3
+ from .results_printer import ResultsPrinter
4
+
5
+
6
+ __all__ = [
7
+ 'JsonPrinter',
8
+ 'TextPrinter',
9
+ 'ResultsPrinter'
10
+ ]
@@ -1,7 +1,9 @@
1
- import click
2
1
  from abc import ABC, abstractmethod
3
2
  from typing import List
4
- from cli.models import DocumentDetections
3
+
4
+ import click
5
+
6
+ from cycode.cli.models import DocumentDetections
5
7
 
6
8
 
7
9
  class BasePrinter(ABC):
@@ -3,9 +3,9 @@ from typing import List
3
3
 
4
4
  import click
5
5
 
6
- from cli.models import DocumentDetections
7
- from cli.printers.base_printer import BasePrinter
8
- from cyclient.models import DetectionSchema, Detection
6
+ from cycode.cli.models import DocumentDetections
7
+ from cycode.cli.printers.base_printer import BasePrinter
8
+ from cycode.cyclient.models import DetectionSchema
9
9
 
10
10
 
11
11
  class JsonPrinter(BasePrinter):
@@ -1,10 +1,10 @@
1
1
  import click
2
2
  from typing import List
3
3
 
4
- from cli.consts import SCA_SCAN_TYPE
5
- from cli.printers import JsonPrinter, TextPrinter
6
- from cli.models import DocumentDetections
7
- from cli.printers.table_printer import TablePrinter
4
+ from cycode.cli.consts import SCA_SCAN_TYPE
5
+ from cycode.cli.printers import JsonPrinter, TextPrinter
6
+ from cycode.cli.models import DocumentDetections
7
+ from cycode.cli.printers.table_printer import TablePrinter
8
8
 
9
9
 
10
10
  class ResultsPrinter: