cycode 3.7.2.dev1__tar.gz → 3.7.2.dev2__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 (176) hide show
  1. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/PKG-INFO +16 -5
  2. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/README.md +15 -4
  3. cycode-3.7.2.dev2/cycode/__init__.py +1 -0
  4. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/app.py +8 -0
  5. cycode-3.7.2.dev2/cycode/cli/apps/auth/auth_common.py +69 -0
  6. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/configure/configure_command.py +10 -1
  7. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/configure/prompts.py +11 -0
  8. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/config.py +1 -0
  9. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/credentials_manager.py +25 -1
  10. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/get_api_client.py +27 -5
  11. cycode-3.7.2.dev1/cycode/cyclient/cycode_token_based_client.py → cycode-3.7.2.dev2/cycode/cyclient/base_token_auth_client.py +21 -18
  12. cycode-3.7.2.dev2/cycode/cyclient/client_creator.py +51 -0
  13. cycode-3.7.2.dev2/cycode/cyclient/cycode_oidc_based_client.py +24 -0
  14. cycode-3.7.2.dev2/cycode/cyclient/cycode_token_based_client.py +24 -0
  15. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/pyproject.toml +1 -1
  16. cycode-3.7.2.dev1/cycode/__init__.py +0 -1
  17. cycode-3.7.2.dev1/cycode/cli/apps/auth/auth_common.py +0 -34
  18. cycode-3.7.2.dev1/cycode/cyclient/client_creator.py +0 -29
  19. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/LICENCE +0 -0
  20. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/__main__.py +0 -0
  21. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/__init__.py +0 -0
  22. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/__init__.py +0 -0
  23. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  24. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  25. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  26. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  27. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/auth/__init__.py +0 -0
  28. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/auth/auth_command.py +0 -0
  29. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/auth/auth_manager.py +0 -0
  30. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/auth/models.py +0 -0
  31. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/configure/__init__.py +0 -0
  32. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/configure/consts.py +0 -0
  33. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/configure/messages.py +0 -0
  34. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ignore/__init__.py +0 -0
  35. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  36. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/mcp/__init__.py +0 -0
  37. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  38. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/__init__.py +0 -0
  39. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/report_command.py +0 -0
  40. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  41. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/common.py +0 -0
  42. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  43. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
  44. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  45. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  46. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  47. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  48. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report_import/__init__.py +0 -0
  49. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report_import/report_import_command.py +0 -0
  50. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report_import/sbom/__init__.py +0 -0
  51. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/report_import/sbom/sbom_command.py +0 -0
  52. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/__init__.py +0 -0
  53. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  54. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/code_scanner.py +0 -0
  55. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  56. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  57. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
  58. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  59. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/path/__init__.py +0 -0
  60. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/path/path_command.py +0 -0
  61. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  62. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
  63. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_push/__init__.py +0 -0
  64. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_push/pre_push_command.py +0 -0
  65. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
  66. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
  67. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  68. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/repository/__init__.py +0 -0
  69. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  70. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
  71. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  72. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  73. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_command.py +0 -0
  74. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  75. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/scan/scan_result.py +0 -0
  76. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/status/__init__.py +0 -0
  77. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/status/get_cli_status.py +0 -0
  78. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/status/models.py +0 -0
  79. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/status/status_command.py +0 -0
  80. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/apps/status/version_command.py +0 -0
  81. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/cli_types.py +0 -0
  82. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/console.py +0 -0
  83. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/consts.py +0 -0
  84. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/__init__.py +0 -0
  85. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/custom_exceptions.py +0 -0
  86. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  87. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  88. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/handle_errors.py +0 -0
  89. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  90. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
  91. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/__init__.py +0 -0
  92. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/commit_range_documents.py +0 -0
  93. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/documents_walk_ignore.py +0 -0
  94. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/file_excluder.py +0 -0
  95. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/iac/__init__.py +0 -0
  96. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  97. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/models/__init__.py +0 -0
  98. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  99. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/path_documents.py +0 -0
  100. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/repository_documents.py +0 -0
  101. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/__init__.py +0 -0
  102. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
  103. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
  104. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
  105. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
  106. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  107. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  108. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
  109. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
  110. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
  111. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  112. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
  113. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  114. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
  115. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  116. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/sca/sca_file_collector.py +0 -0
  117. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/walk_ignore.py +0 -0
  118. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/files_collector/zip_documents.py +0 -0
  119. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/logger.py +0 -0
  120. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/main.py +0 -0
  121. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/models.py +0 -0
  122. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/__init__.py +0 -0
  123. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/console_printer.py +0 -0
  124. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/json_printer.py +0 -0
  125. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/printer_base.py +0 -0
  126. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/rich_printer.py +0 -0
  127. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/__init__.py +0 -0
  128. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  129. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/table.py +0 -0
  130. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/table_models.py +0 -0
  131. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/table_printer.py +0 -0
  132. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  133. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/text_printer.py +0 -0
  134. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/__init__.py +0 -0
  135. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  136. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/detection_data.py +0 -0
  137. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
  138. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  139. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  140. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  141. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/__init__.py +0 -0
  142. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/base_file_manager.py +0 -0
  143. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/config_file_manager.py +0 -0
  144. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/configuration_manager.py +0 -0
  145. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/user_settings/jwt_creator.py +0 -0
  146. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/__init__.py +0 -0
  147. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/enum_utils.py +0 -0
  148. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/git_proxy.py +0 -0
  149. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/ignore_utils.py +0 -0
  150. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/jwt_utils.py +0 -0
  151. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/path_utils.py +0 -0
  152. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/progress_bar.py +0 -0
  153. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/scan_batch.py +0 -0
  154. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/scan_utils.py +0 -0
  155. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/sentry.py +0 -0
  156. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/shell_executor.py +0 -0
  157. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/string_utils.py +0 -0
  158. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/task_timer.py +0 -0
  159. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/version_checker.py +0 -0
  160. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cli/utils/yaml_utils.py +0 -0
  161. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/config.py +0 -0
  162. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/__init__.py +0 -0
  163. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/auth_client.py +0 -0
  164. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/config.py +0 -0
  165. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/config_dev.py +0 -0
  166. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/cycode_client.py +0 -0
  167. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/cycode_client_base.py +0 -0
  168. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  169. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/headers.py +0 -0
  170. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/import_sbom_client.py +0 -0
  171. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/logger.py +0 -0
  172. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/models.py +0 -0
  173. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/report_client.py +0 -0
  174. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/scan_client.py +0 -0
  175. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/cyclient/scan_config_base.py +0 -0
  176. {cycode-3.7.2.dev1 → cycode-3.7.2.dev2}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.7.2.dev1
3
+ Version: 3.7.2.dev2
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  License-Expression: MIT
6
6
  License-File: LICENCE
@@ -144,7 +144,7 @@ To install the Cycode CLI application on your local machine, perform the followi
144
144
  ./cycode
145
145
  ```
146
146
 
147
- 3. Finally authenticate the CLI. There are three methods to set the Cycode client ID and client secret:
147
+ 3. Finally authenticate the CLI. There are three methods to set the Cycode client ID and credentials (client secret or OIDC ID token):
148
148
 
149
149
  - [cycode auth](#using-the-auth-command) (**Recommended**)
150
150
  - [cycode configure](#using-the-configure-command)
@@ -207,11 +207,15 @@ To install the Cycode CLI application on your local machine, perform the followi
207
207
 
208
208
  `Cycode Client ID []: 7fe5346b-xxxx-xxxx-xxxx-55157625c72d`
209
209
 
210
- 5. Enter your Cycode Client Secret value.
210
+ 5. Enter your Cycode Client Secret value (skip if you plan to use an OIDC ID token).
211
211
 
212
212
  `Cycode Client Secret []: c1e24929-xxxx-xxxx-xxxx-8b08c1839a2e`
213
213
 
214
- 6. If the values were entered successfully, you'll see the following message:
214
+ 6. Enter your Cycode OIDC ID Token value (optional).
215
+
216
+ `Cycode ID Token []: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...`
217
+
218
+ 7. If the values were entered successfully, you'll see the following message:
215
219
 
216
220
  `Successfully configured CLI credentials!`
217
221
 
@@ -236,6 +240,12 @@ and
236
240
  export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
237
241
  ```
238
242
 
243
+ If your organization uses OIDC authentication, you can provide the ID token instead (or in addition):
244
+
245
+ ```bash
246
+ export CYCODE_ID_TOKEN={your Cycode OIDC ID token}
247
+ ```
248
+
239
249
  #### On Windows
240
250
 
241
251
  1. From the Control Panel, navigate to the System menu:
@@ -250,7 +260,7 @@ export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
250
260
 
251
261
  <img height="30" src="https://raw.githubusercontent.com/cycodehq/cycode-cli/main/images/image3.png" alt="environments variables button"/>
252
262
 
253
- 4. Create `CYCODE_CLIENT_ID` and `CYCODE_CLIENT_SECRET` variables with values matching your ID and Secret Key, respectively:
263
+ 4. Create `CYCODE_CLIENT_ID` and `CYCODE_CLIENT_SECRET` variables with values matching your ID and Secret Key, respectively. If you authenticate via OIDC, add `CYCODE_ID_TOKEN` with your OIDC ID token value as well:
254
264
 
255
265
  <img height="100" src="https://raw.githubusercontent.com/cycodehq/cycode-cli/main/images/image4.png" alt="environment variables window"/>
256
266
 
@@ -364,6 +374,7 @@ The following are the options and commands available with the Cycode CLI applica
364
374
  | `-o`, `--output [rich\|text\|json\|table]` | Specify the output type. The default is `rich`. |
365
375
  | `--client-id TEXT` | Specify a Cycode client ID for this specific scan execution. |
366
376
  | `--client-secret TEXT` | Specify a Cycode client secret for this specific scan execution. |
377
+ | `--id-token TEXT` | Specify a Cycode OIDC ID token for this specific scan execution. |
367
378
  | `--install-completion` | Install completion for the current shell.. |
368
379
  | `--show-completion [bash\|zsh\|fish\|powershell\|pwsh]` | Show completion for the specified shell, to copy it or customize the installation. |
369
380
  | `-h`, `--help` | Show options for given command. |
@@ -101,7 +101,7 @@ To install the Cycode CLI application on your local machine, perform the followi
101
101
  ./cycode
102
102
  ```
103
103
 
104
- 3. Finally authenticate the CLI. There are three methods to set the Cycode client ID and client secret:
104
+ 3. Finally authenticate the CLI. There are three methods to set the Cycode client ID and credentials (client secret or OIDC ID token):
105
105
 
106
106
  - [cycode auth](#using-the-auth-command) (**Recommended**)
107
107
  - [cycode configure](#using-the-configure-command)
@@ -164,11 +164,15 @@ To install the Cycode CLI application on your local machine, perform the followi
164
164
 
165
165
  `Cycode Client ID []: 7fe5346b-xxxx-xxxx-xxxx-55157625c72d`
166
166
 
167
- 5. Enter your Cycode Client Secret value.
167
+ 5. Enter your Cycode Client Secret value (skip if you plan to use an OIDC ID token).
168
168
 
169
169
  `Cycode Client Secret []: c1e24929-xxxx-xxxx-xxxx-8b08c1839a2e`
170
170
 
171
- 6. If the values were entered successfully, you'll see the following message:
171
+ 6. Enter your Cycode OIDC ID Token value (optional).
172
+
173
+ `Cycode ID Token []: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...`
174
+
175
+ 7. If the values were entered successfully, you'll see the following message:
172
176
 
173
177
  `Successfully configured CLI credentials!`
174
178
 
@@ -193,6 +197,12 @@ and
193
197
  export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
194
198
  ```
195
199
 
200
+ If your organization uses OIDC authentication, you can provide the ID token instead (or in addition):
201
+
202
+ ```bash
203
+ export CYCODE_ID_TOKEN={your Cycode OIDC ID token}
204
+ ```
205
+
196
206
  #### On Windows
197
207
 
198
208
  1. From the Control Panel, navigate to the System menu:
@@ -207,7 +217,7 @@ export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
207
217
 
208
218
  <img height="30" src="https://raw.githubusercontent.com/cycodehq/cycode-cli/main/images/image3.png" alt="environments variables button"/>
209
219
 
210
- 4. Create `CYCODE_CLIENT_ID` and `CYCODE_CLIENT_SECRET` variables with values matching your ID and Secret Key, respectively:
220
+ 4. Create `CYCODE_CLIENT_ID` and `CYCODE_CLIENT_SECRET` variables with values matching your ID and Secret Key, respectively. If you authenticate via OIDC, add `CYCODE_ID_TOKEN` with your OIDC ID token value as well:
211
221
 
212
222
  <img height="100" src="https://raw.githubusercontent.com/cycodehq/cycode-cli/main/images/image4.png" alt="environment variables window"/>
213
223
 
@@ -321,6 +331,7 @@ The following are the options and commands available with the Cycode CLI applica
321
331
  | `-o`, `--output [rich\|text\|json\|table]` | Specify the output type. The default is `rich`. |
322
332
  | `--client-id TEXT` | Specify a Cycode client ID for this specific scan execution. |
323
333
  | `--client-secret TEXT` | Specify a Cycode client secret for this specific scan execution. |
334
+ | `--id-token TEXT` | Specify a Cycode OIDC ID token for this specific scan execution. |
324
335
  | `--install-completion` | Install completion for the current shell.. |
325
336
  | `--show-completion [bash\|zsh\|fish\|powershell\|pwsh]` | Show completion for the specified shell, to copy it or customize the installation. |
326
337
  | `-h`, `--help` | Show options for given command. |
@@ -0,0 +1 @@
1
+ __version__ = '3.7.2.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -110,6 +110,13 @@ def app_callback(
110
110
  rich_help_panel=_AUTH_RICH_HELP_PANEL,
111
111
  ),
112
112
  ] = None,
113
+ id_token: Annotated[
114
+ Optional[str],
115
+ typer.Option(
116
+ help='Specify a Cycode OIDC ID token for this specific scan execution.',
117
+ rich_help_panel=_AUTH_RICH_HELP_PANEL,
118
+ ),
119
+ ] = None,
113
120
  _: Annotated[
114
121
  Optional[bool],
115
122
  typer.Option(
@@ -152,6 +159,7 @@ def app_callback(
152
159
 
153
160
  ctx.obj['client_id'] = client_id
154
161
  ctx.obj['client_secret'] = client_secret
162
+ ctx.obj['id_token'] = id_token
155
163
 
156
164
  ctx.obj['progress_bar'] = get_progress_bar(hidden=no_progress_meter, sections=SCAN_PROGRESS_BAR_SECTIONS)
157
165
 
@@ -0,0 +1,69 @@
1
+ from typing import TYPE_CHECKING, Optional
2
+
3
+ from cycode.cli.apps.auth.models import AuthInfo
4
+ from cycode.cli.exceptions.custom_exceptions import HttpUnauthorizedError, RequestHttpError
5
+ from cycode.cli.user_settings.credentials_manager import CredentialsManager
6
+ from cycode.cli.utils.jwt_utils import get_user_and_tenant_ids_from_access_token
7
+ from cycode.cyclient.cycode_oidc_based_client import CycodeOidcBasedClient
8
+ from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
9
+
10
+ if TYPE_CHECKING:
11
+ from typer import Context
12
+
13
+
14
+ def get_authorization_info(ctx: 'Context') -> Optional[AuthInfo]:
15
+ printer = ctx.obj.get('console_printer')
16
+
17
+ client_id = ctx.obj.get('client_id')
18
+ client_secret = ctx.obj.get('client_secret')
19
+ id_token = ctx.obj.get('id_token')
20
+
21
+ credentials_manager = CredentialsManager()
22
+
23
+ auth_info = _try_oidc_authorization(ctx, printer, client_id, id_token)
24
+ if auth_info:
25
+ return auth_info
26
+
27
+ if not client_id or not client_secret:
28
+ stored_client_id, stored_id_token = credentials_manager.get_oidc_credentials()
29
+ auth_info = _try_oidc_authorization(ctx, printer, stored_client_id, stored_id_token)
30
+ if auth_info:
31
+ return auth_info
32
+
33
+ client_id, client_secret = credentials_manager.get_credentials()
34
+
35
+ if not client_id or not client_secret:
36
+ return None
37
+
38
+ try:
39
+ access_token = CycodeTokenBasedClient(client_id, client_secret).get_access_token()
40
+ if not access_token:
41
+ return None
42
+
43
+ user_id, tenant_id = get_user_and_tenant_ids_from_access_token(access_token)
44
+ return AuthInfo(user_id=user_id, tenant_id=tenant_id)
45
+ except (RequestHttpError, HttpUnauthorizedError):
46
+ if ctx:
47
+ printer.print_exception()
48
+
49
+ return None
50
+
51
+
52
+ def _try_oidc_authorization(
53
+ ctx: 'Context', printer: any, client_id: Optional[str], id_token: Optional[str]
54
+ ) -> Optional[AuthInfo]:
55
+ if not client_id or not id_token:
56
+ return None
57
+
58
+ try:
59
+ access_token = CycodeOidcBasedClient(client_id, id_token).get_access_token()
60
+ if not access_token:
61
+ return None
62
+
63
+ user_id, tenant_id = get_user_and_tenant_ids_from_access_token(access_token)
64
+ return AuthInfo(user_id=user_id, tenant_id=tenant_id)
65
+ except (RequestHttpError, HttpUnauthorizedError):
66
+ if ctx:
67
+ printer.print_exception()
68
+
69
+ return None
@@ -7,6 +7,7 @@ from cycode.cli.apps.configure.prompts import (
7
7
  get_app_url_input,
8
8
  get_client_id_input,
9
9
  get_client_secret_input,
10
+ get_id_token_input,
10
11
  )
11
12
  from cycode.cli.console import console
12
13
  from cycode.cli.utils.sentry import add_breadcrumb
@@ -32,6 +33,7 @@ def configure_command() -> None:
32
33
  * APP URL: The base URL for Cycode's web application (for on-premise or EU installations)
33
34
  * Client ID: Your Cycode client ID for authentication
34
35
  * Client Secret: Your Cycode client secret for authentication
36
+ * ID Token: Your Cycode ID token for authentication
35
37
 
36
38
  Example usage:
37
39
  * `cycode configure`: Start interactive configuration
@@ -55,15 +57,22 @@ def configure_command() -> None:
55
57
  config_updated = True
56
58
 
57
59
  current_client_id, current_client_secret = CREDENTIALS_MANAGER.get_credentials_from_file()
60
+ _, current_id_token = CREDENTIALS_MANAGER.get_oidc_credentials_from_file()
58
61
  client_id = get_client_id_input(current_client_id)
59
62
  client_secret = get_client_secret_input(current_client_secret)
63
+ id_token = get_id_token_input(current_id_token)
60
64
 
61
65
  credentials_updated = False
62
66
  if _should_update_value(current_client_id, client_id) or _should_update_value(current_client_secret, client_secret):
63
67
  credentials_updated = True
64
68
  CREDENTIALS_MANAGER.update_credentials(client_id, client_secret)
65
69
 
70
+ oidc_credentials_updated = False
71
+ if _should_update_value(current_client_id, client_id) or _should_update_value(current_id_token, id_token):
72
+ oidc_credentials_updated = True
73
+ CREDENTIALS_MANAGER.update_oidc_credentials(client_id, id_token)
74
+
66
75
  if config_updated:
67
76
  console.print(get_urls_update_result_message())
68
- if credentials_updated:
77
+ if credentials_updated or oidc_credentials_updated:
69
78
  console.print(get_credentials_update_result_message())
@@ -46,3 +46,14 @@ def get_api_url_input(current_api_url: Optional[str]) -> str:
46
46
  default = current_api_url
47
47
 
48
48
  return typer.prompt(text=prompt_text, default=default, type=str)
49
+
50
+
51
+ def get_id_token_input(current_id_token: Optional[str]) -> Optional[str]:
52
+ prompt_text = 'Cycode ID Token'
53
+
54
+ prompt_suffix = ' []: '
55
+ if current_id_token:
56
+ prompt_suffix = f' [{obfuscate_text(current_id_token)}]: '
57
+
58
+ new_id_token = typer.prompt(text=prompt_text, prompt_suffix=prompt_suffix, default='', show_default=False)
59
+ return new_id_token or current_id_token
@@ -5,3 +5,4 @@ configuration_manager = ConfigurationManager()
5
5
  # env vars
6
6
  CYCODE_CLIENT_ID_ENV_VAR_NAME = 'CYCODE_CLIENT_ID'
7
7
  CYCODE_CLIENT_SECRET_ENV_VAR_NAME = 'CYCODE_CLIENT_SECRET'
8
+ CYCODE_ID_TOKEN_ENV_VAR_NAME = 'CYCODE_ID_TOKEN'
@@ -2,7 +2,11 @@ import os
2
2
  from pathlib import Path
3
3
  from typing import Optional
4
4
 
5
- from cycode.cli.config import CYCODE_CLIENT_ID_ENV_VAR_NAME, CYCODE_CLIENT_SECRET_ENV_VAR_NAME
5
+ from cycode.cli.config import (
6
+ CYCODE_CLIENT_ID_ENV_VAR_NAME,
7
+ CYCODE_CLIENT_SECRET_ENV_VAR_NAME,
8
+ CYCODE_ID_TOKEN_ENV_VAR_NAME,
9
+ )
6
10
  from cycode.cli.user_settings.base_file_manager import BaseFileManager
7
11
  from cycode.cli.user_settings.jwt_creator import JwtCreator
8
12
  from cycode.cli.utils.sentry import setup_scope_from_access_token
@@ -15,6 +19,7 @@ class CredentialsManager(BaseFileManager):
15
19
 
16
20
  CLIENT_ID_FIELD_NAME: str = 'cycode_client_id'
17
21
  CLIENT_SECRET_FIELD_NAME: str = 'cycode_client_secret'
22
+ ID_TOKEN_FIELD_NAME: str = 'cycode_id_token'
18
23
  ACCESS_TOKEN_FIELD_NAME: str = 'cycode_access_token'
19
24
  ACCESS_TOKEN_EXPIRES_IN_FIELD_NAME: str = 'cycode_access_token_expires_in'
20
25
  ACCESS_TOKEN_CREATOR_FIELD_NAME: str = 'cycode_access_token_creator'
@@ -38,6 +43,25 @@ class CredentialsManager(BaseFileManager):
38
43
  client_secret = file_content.get(self.CLIENT_SECRET_FIELD_NAME)
39
44
  return client_id, client_secret
40
45
 
46
+ def get_oidc_credentials_from_file(self) -> tuple[Optional[str], Optional[str]]:
47
+ file_content = self.read_file()
48
+ client_id = file_content.get(self.CLIENT_ID_FIELD_NAME)
49
+ id_token = file_content.get(self.ID_TOKEN_FIELD_NAME)
50
+ return client_id, id_token
51
+
52
+ def get_oidc_credentials(self) -> tuple[Optional[str], Optional[str]]:
53
+ client_id = os.getenv(CYCODE_CLIENT_ID_ENV_VAR_NAME)
54
+ id_token = os.getenv(CYCODE_ID_TOKEN_ENV_VAR_NAME)
55
+
56
+ if client_id is not None and id_token is not None:
57
+ return client_id, id_token
58
+
59
+ return self.get_oidc_credentials_from_file()
60
+
61
+ def update_oidc_credentials(self, client_id: str, id_token: str) -> None:
62
+ file_content_to_update = {self.CLIENT_ID_FIELD_NAME: client_id, self.ID_TOKEN_FIELD_NAME: id_token}
63
+ self.write_content_to_file(file_content_to_update)
64
+
41
65
  def update_credentials(self, client_id: str, client_secret: str) -> None:
42
66
  file_content_to_update = {self.CLIENT_ID_FIELD_NAME: client_id, self.CLIENT_SECRET_FIELD_NAME: client_secret}
43
67
  self.write_content_to_file(file_content_to_update)
@@ -14,8 +14,22 @@ if TYPE_CHECKING:
14
14
 
15
15
 
16
16
  def _get_cycode_client(
17
- create_client_func: callable, client_id: Optional[str], client_secret: Optional[str], hide_response_log: bool
17
+ create_client_func: callable,
18
+ client_id: Optional[str],
19
+ client_secret: Optional[str],
20
+ hide_response_log: bool,
21
+ id_token: Optional[str] = None,
18
22
  ) -> Union['ScanClient', 'ReportClient']:
23
+ if client_id and id_token:
24
+ return create_client_func(client_id, None, hide_response_log, id_token)
25
+
26
+ if not client_id or not id_token:
27
+ oidc_client_id, oidc_id_token = _get_configured_oidc_credentials()
28
+ if oidc_client_id and oidc_id_token:
29
+ return create_client_func(oidc_client_id, None, hide_response_log, oidc_id_token)
30
+ if oidc_id_token and not oidc_client_id:
31
+ raise click.ClickException('Cycode client id needed for OIDC authentication.')
32
+
19
33
  if not client_id or not client_secret:
20
34
  client_id, client_secret = _get_configured_credentials()
21
35
  if not client_id:
@@ -23,28 +37,36 @@ def _get_cycode_client(
23
37
  if not client_secret:
24
38
  raise click.ClickException('Cycode client secret is needed.')
25
39
 
26
- return create_client_func(client_id, client_secret, hide_response_log)
40
+ return create_client_func(client_id, client_secret, hide_response_log, None)
27
41
 
28
42
 
29
43
  def get_scan_cycode_client(ctx: 'typer.Context') -> 'ScanClient':
30
44
  client_id = ctx.obj.get('client_id')
31
45
  client_secret = ctx.obj.get('client_secret')
46
+ id_token = ctx.obj.get('id_token')
32
47
  hide_response_log = not ctx.obj.get('show_secret', False)
33
- return _get_cycode_client(create_scan_client, client_id, client_secret, hide_response_log)
48
+ return _get_cycode_client(create_scan_client, client_id, client_secret, hide_response_log, id_token)
34
49
 
35
50
 
36
51
  def get_report_cycode_client(ctx: 'typer.Context', hide_response_log: bool = True) -> 'ReportClient':
37
52
  client_id = ctx.obj.get('client_id')
38
53
  client_secret = ctx.obj.get('client_secret')
39
- return _get_cycode_client(create_report_client, client_id, client_secret, hide_response_log)
54
+ id_token = ctx.obj.get('id_token')
55
+ return _get_cycode_client(create_report_client, client_id, client_secret, hide_response_log, id_token)
40
56
 
41
57
 
42
58
  def get_import_sbom_cycode_client(ctx: 'typer.Context', hide_response_log: bool = True) -> 'ImportSbomClient':
43
59
  client_id = ctx.obj.get('client_id')
44
60
  client_secret = ctx.obj.get('client_secret')
45
- return _get_cycode_client(create_import_sbom_client, client_id, client_secret, hide_response_log)
61
+ id_token = ctx.obj.get('id_token')
62
+ return _get_cycode_client(create_import_sbom_client, client_id, client_secret, hide_response_log, id_token)
46
63
 
47
64
 
48
65
  def _get_configured_credentials() -> tuple[str, str]:
49
66
  credentials_manager = CredentialsManager()
50
67
  return credentials_manager.get_credentials()
68
+
69
+
70
+ def _get_configured_oidc_credentials() -> tuple[Optional[str], Optional[str]]:
71
+ credentials_manager = CredentialsManager()
72
+ return credentials_manager.get_oidc_credentials()
@@ -1,5 +1,6 @@
1
+ from abc import ABC, abstractmethod
1
2
  from threading import Lock
2
- from typing import Optional
3
+ from typing import Any, Optional
3
4
 
4
5
  import arrow
5
6
  from requests import Response
@@ -15,12 +16,11 @@ _NGINX_PLAIN_ERRORS = [
15
16
  ]
16
17
 
17
18
 
18
- class CycodeTokenBasedClient(CycodeClient):
19
- """Send requests with JWT."""
19
+ class BaseTokenAuthClient(CycodeClient, ABC):
20
+ """Base client for token-based authentication flows with cached JWTs."""
20
21
 
21
- def __init__(self, client_id: str, client_secret: str) -> None:
22
+ def __init__(self, client_id: str) -> None:
22
23
  super().__init__()
23
- self.client_secret = client_secret
24
24
  self.client_id = client_id
25
25
 
26
26
  self._credentials_manager = CredentialsManager()
@@ -28,7 +28,8 @@ class CycodeTokenBasedClient(CycodeClient):
28
28
  access_token, expires_in, creator = self._credentials_manager.get_access_token()
29
29
 
30
30
  self._access_token = self._expires_in = None
31
- if creator == JwtCreator.create(client_id, client_secret):
31
+ expected_creator = self._create_jwt_creator()
32
+ if creator == expected_creator:
32
33
  # we must be sure that cached access token is created using the same client id and client secret.
33
34
  # because client id and client secret could be passed via command, via env vars or via config file.
34
35
  # we must not use cached access token if client id or client secret was changed.
@@ -54,18 +55,12 @@ class CycodeTokenBasedClient(CycodeClient):
54
55
  self.refresh_access_token()
55
56
 
56
57
  def refresh_access_token(self) -> None:
57
- auth_response = self.post(
58
- url_path='api/v1/auth/api-token',
59
- body={'clientId': self.client_id, 'secret': self.client_secret},
60
- without_auth=True,
61
- hide_response_content_log=True,
62
- )
63
- auth_response_data = auth_response.json()
64
-
65
- self._access_token = auth_response_data['token']
66
- self._expires_in = arrow.utcnow().shift(seconds=auth_response_data['expires_in'] * 0.8)
67
-
68
- jwt_creator = JwtCreator.create(self.client_id, self.client_secret)
58
+ auth_response = self._request_new_access_token()
59
+ self._access_token = auth_response['token']
60
+
61
+ self._expires_in = arrow.utcnow().shift(seconds=auth_response['expires_in'] * 0.8)
62
+
63
+ jwt_creator = self._create_jwt_creator()
69
64
  self._credentials_manager.update_access_token(self._access_token, self._expires_in.timestamp(), jwt_creator)
70
65
 
71
66
  def get_request_headers(self, additional_headers: Optional[dict] = None, without_auth: bool = False) -> dict:
@@ -95,3 +90,11 @@ class CycodeTokenBasedClient(CycodeClient):
95
90
  response = super()._execute(*args, **kwargs)
96
91
 
97
92
  return response
93
+
94
+ @abstractmethod
95
+ def _create_jwt_creator(self) -> JwtCreator:
96
+ """Create a JwtCreator instance for the current credential type."""
97
+
98
+ @abstractmethod
99
+ def _request_new_access_token(self) -> dict[str, Any]:
100
+ """Return the authentication payload with token and expires_in."""
@@ -0,0 +1,51 @@
1
+ from typing import Optional
2
+
3
+ from cycode.cyclient.config import dev_mode
4
+ from cycode.cyclient.config_dev import DEV_CYCODE_API_URL
5
+ from cycode.cyclient.cycode_dev_based_client import CycodeDevBasedClient
6
+ from cycode.cyclient.cycode_oidc_based_client import CycodeOidcBasedClient
7
+ from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
8
+ from cycode.cyclient.import_sbom_client import ImportSbomClient
9
+ from cycode.cyclient.report_client import ReportClient
10
+ from cycode.cyclient.scan_client import ScanClient
11
+ from cycode.cyclient.scan_config_base import DefaultScanConfig, DevScanConfig
12
+
13
+
14
+ def create_scan_client(
15
+ client_id: str, client_secret: Optional[str] = None, hide_response_log: bool = False, id_token: Optional[str] = None
16
+ ) -> ScanClient:
17
+ if dev_mode:
18
+ client = CycodeDevBasedClient(DEV_CYCODE_API_URL)
19
+ scan_config = DevScanConfig()
20
+ else:
21
+ if id_token:
22
+ client = CycodeOidcBasedClient(client_id, id_token)
23
+ else:
24
+ client = CycodeTokenBasedClient(client_id, client_secret)
25
+ scan_config = DefaultScanConfig()
26
+
27
+ return ScanClient(client, scan_config, hide_response_log)
28
+
29
+
30
+ def create_report_client(
31
+ client_id: str, client_secret: Optional[str] = None, _: bool = False, id_token: Optional[str] = None
32
+ ) -> ReportClient:
33
+ if dev_mode:
34
+ client = CycodeDevBasedClient(DEV_CYCODE_API_URL)
35
+ elif id_token:
36
+ client = CycodeOidcBasedClient(client_id, id_token)
37
+ else:
38
+ client = CycodeTokenBasedClient(client_id, client_secret)
39
+ return ReportClient(client)
40
+
41
+
42
+ def create_import_sbom_client(
43
+ client_id: str, client_secret: Optional[str] = None, _: bool = False, id_token: Optional[str] = None
44
+ ) -> ImportSbomClient:
45
+ if dev_mode:
46
+ client = CycodeDevBasedClient(DEV_CYCODE_API_URL)
47
+ elif id_token:
48
+ client = CycodeOidcBasedClient(client_id, id_token)
49
+ else:
50
+ client = CycodeTokenBasedClient(client_id, client_secret)
51
+ return ImportSbomClient(client)
@@ -0,0 +1,24 @@
1
+ from typing import Any
2
+
3
+ from cycode.cli.user_settings.jwt_creator import JwtCreator
4
+ from cycode.cyclient.base_token_auth_client import BaseTokenAuthClient
5
+
6
+
7
+ class CycodeOidcBasedClient(BaseTokenAuthClient):
8
+ """Send requests with JWT obtained via OIDC ID token."""
9
+
10
+ def __init__(self, client_id: str, id_token: str) -> None:
11
+ self.id_token = id_token
12
+ super().__init__(client_id)
13
+
14
+ def _request_new_access_token(self) -> dict[str, Any]:
15
+ auth_response = self.post(
16
+ url_path='api/v1/auth/oidc/api-token',
17
+ body={'client_id': self.client_id, 'id_token': self.id_token},
18
+ without_auth=True,
19
+ hide_response_content_log=True,
20
+ )
21
+ return auth_response.json()
22
+
23
+ def _create_jwt_creator(self) -> JwtCreator:
24
+ return JwtCreator.create(self.client_id, self.id_token)
@@ -0,0 +1,24 @@
1
+ from typing import Any
2
+
3
+ from cycode.cli.user_settings.jwt_creator import JwtCreator
4
+ from cycode.cyclient.base_token_auth_client import BaseTokenAuthClient
5
+
6
+
7
+ class CycodeTokenBasedClient(BaseTokenAuthClient):
8
+ """Send requests with JWT."""
9
+
10
+ def __init__(self, client_id: str, client_secret: str) -> None:
11
+ self.client_secret = client_secret
12
+ super().__init__(client_id)
13
+
14
+ def _request_new_access_token(self) -> dict[str, Any]:
15
+ auth_response = self.post(
16
+ url_path='api/v1/auth/api-token',
17
+ body={'clientId': self.client_id, 'secret': self.client_secret},
18
+ without_auth=True,
19
+ hide_response_content_log=True,
20
+ )
21
+ return auth_response.json()
22
+
23
+ def _create_jwt_creator(self) -> JwtCreator:
24
+ return JwtCreator.create(self.client_id, self.client_secret)
@@ -21,7 +21,7 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.14",
22
22
  ]
23
23
  dynamic = ["dependencies"]
24
- version = "3.7.2.dev1"
24
+ version = "3.7.2.dev2"
25
25
 
26
26
  [project.scripts]
27
27
  cycode = "cycode.cli.app:app"
@@ -1 +0,0 @@
1
- __version__ = '3.7.2.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -1,34 +0,0 @@
1
- from typing import TYPE_CHECKING, Optional
2
-
3
- from cycode.cli.apps.auth.models import AuthInfo
4
- from cycode.cli.exceptions.custom_exceptions import HttpUnauthorizedError, RequestHttpError
5
- from cycode.cli.user_settings.credentials_manager import CredentialsManager
6
- from cycode.cli.utils.jwt_utils import get_user_and_tenant_ids_from_access_token
7
- from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
8
-
9
- if TYPE_CHECKING:
10
- from typer import Context
11
-
12
-
13
- def get_authorization_info(ctx: 'Context') -> Optional[AuthInfo]:
14
- printer = ctx.obj.get('console_printer')
15
-
16
- client_id, client_secret = ctx.obj.get('client_id'), ctx.obj.get('client_secret')
17
- if not client_id or not client_secret:
18
- client_id, client_secret = CredentialsManager().get_credentials()
19
-
20
- if not client_id or not client_secret:
21
- return None
22
-
23
- try:
24
- access_token = CycodeTokenBasedClient(client_id, client_secret).get_access_token()
25
- if not access_token:
26
- return None
27
-
28
- user_id, tenant_id = get_user_and_tenant_ids_from_access_token(access_token)
29
- return AuthInfo(user_id=user_id, tenant_id=tenant_id)
30
- except (RequestHttpError, HttpUnauthorizedError):
31
- if ctx:
32
- printer.print_exception()
33
-
34
- return None
@@ -1,29 +0,0 @@
1
- from cycode.cyclient.config import dev_mode
2
- from cycode.cyclient.config_dev import DEV_CYCODE_API_URL
3
- from cycode.cyclient.cycode_dev_based_client import CycodeDevBasedClient
4
- from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
5
- from cycode.cyclient.import_sbom_client import ImportSbomClient
6
- from cycode.cyclient.report_client import ReportClient
7
- from cycode.cyclient.scan_client import ScanClient
8
- from cycode.cyclient.scan_config_base import DefaultScanConfig, DevScanConfig
9
-
10
-
11
- def create_scan_client(client_id: str, client_secret: str, hide_response_log: bool) -> ScanClient:
12
- if dev_mode:
13
- client = CycodeDevBasedClient(DEV_CYCODE_API_URL)
14
- scan_config = DevScanConfig()
15
- else:
16
- client = CycodeTokenBasedClient(client_id, client_secret)
17
- scan_config = DefaultScanConfig()
18
-
19
- return ScanClient(client, scan_config, hide_response_log)
20
-
21
-
22
- def create_report_client(client_id: str, client_secret: str, _: bool) -> ReportClient:
23
- client = CycodeDevBasedClient(DEV_CYCODE_API_URL) if dev_mode else CycodeTokenBasedClient(client_id, client_secret)
24
- return ReportClient(client)
25
-
26
-
27
- def create_import_sbom_client(client_id: str, client_secret: str, _: bool) -> ImportSbomClient:
28
- client = CycodeDevBasedClient(DEV_CYCODE_API_URL) if dev_mode else CycodeTokenBasedClient(client_id, client_secret)
29
- return ImportSbomClient(client)
File without changes