Skip to content

Commit

Permalink
parent f15d790
Browse files Browse the repository at this point in the history
author Dylan Pulver <[email protected]> 1719603852 -0400
committer Dylan Pulver <[email protected]> 1720552637 -0400
gpgsig -----BEGIN PGP SIGNATURE-----

 iHUEABYKAB0WIQQVa+zaLSZxm3/LxmooEm7VNVc3KwUCZo2MvQAKCRAoEm7VNVc3
 Kw3EAP0acAlkZ3XYxvP5P8H4rAx4XXhAOp1Sv7OnQu/nbuPhIgEAitluAgNBdtDU
 jrt9pNq7Y1I76KOuKS+8VRewmuYJUQI=
 =bYzZ
 -----END PGP SIGNATURE-----

fix(debug): fix --debug flag and associated tests

- Fix --debug flag functionality
- Add tests using runner.invoke
- Fix and modify fetch_database function
- Ensure all tests pass with appropriate patchings

Fix --debug flag

remove duplicate block

undo linting

remove test_debug file

modify fetch_database

fix(cache): handle get_from_cache=None and ensure directory exists (#544)

Signed-off-by: Dylan Pulver <[email protected]>

chore: release 3.2.4 (#545)

refactor: Jeff refactor suggestions

Switch to use main() function

refactor: adjust to cli() and cli_internal()

refactor: fix click group to be on new cli() func

fix: fix function order

fix: fix function order

fix: fix tests for debug flag changes

remove uneeded files

don't call dummy funcs

fix(debug): fix --debug flag and associated tests

- Fix --debug flag functionality
- Add tests using runner.invoke
- Fix and modify fetch_database function
- Ensure all tests pass with appropriate patchings

Fix --debug flag

undo linting
  • Loading branch information
dylanpulver committed Jul 9, 2024
1 parent f15d790 commit a76bc42
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 121 deletions.
25 changes: 15 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is partly based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [PEP 440](https://peps.python.org/pep-0440/)

## [3.2.4] - 2024-07-04
- Handle `get_from_cache=None` and ensure directory exists (#538)
- Switch filelock package to compatible release clause (#538)
- Add filelock to `install_requires` (#538)

## [3.2.3] - 2024-06-10
- Increase request timeout to 30 seconds (#535)
- fix: fail on none severities (#534)
Expand Down Expand Up @@ -38,22 +43,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Main updates
- Added scan command, which scans a project’s directory for all Python dependencies and includes many improvements over the `check` command, including automatic Python project scanning, native support for Poetry and Pipenv files, Python virtual environment folders, and more granular configuration options.
- Added auth commands, enabling new browser-based authentication of Safety CLI.
- Added auth commands, enabling new browser-based authentication of Safety CLI.
- An updated safety policy file schema to support new scan and system-scan commands. This policy file schema is a breaking change from the policy schema used for `safety check`. To migrate a Safety 2.x policy, see [Migrating from Safety 2.x to Safety CLI 3](https://docs.safetycli.com/safety-docs/safety-cli-3/migrating-from-safety-cli-2.x-to-safety-cli-3.x).
- Updated screen output to modern interactive interface, with new help interfaces.
- Updated to new JSON output structure to support new scan command, other ecosystems, and other security findings.
- Updated to new JSON output structure to support new scan command, other ecosystems, and other security findings.
- Added a supporting [safety-schemas project dependency](https://pypi.org/project/safety-schemas/), also published and maintained by Safety, which defines Safety vulnerability database file, Safety CLI policy file, and Safety CLI JSON output schemas as pydantic models, formalizing these into testable and versioned schemas.

### New scan command:
- New scan command: scans a Python project directory for Python dependencies and security vulnerabilities. Safety scan replaces `safety check` with a more powerful and easier to use command. The scan command:
- Finds and scans Python dependency files and virtual environments inside the target directory without needing to specify file or environment locations.
- Adds native scanning and reporting for Poetry and Pipenv manifest files, and Python virtual environment folders.
- Adds configuration of scanning rules to;
- Adds configuration of scanning rules to;
- exclude files and folders from the scan using Unix shell-style wildcards only
- Include files to be scanned
- Max folder depth setting
- Reporting configuration rules
- Reporting rules defining which types and specific vulnerabilities to include or ignore stay the same as safety 2.x, although now in a slightly different structure.
- Reporting rules defining which types and specific vulnerabilities to include or ignore stay the same as safety 2.x, although now in a slightly different structure.
- Failing rules
- Adds ability to configure rules for when safety should return a non-zero (failing) exit code, which can be different from reporting rules under the `report` field.
- Auto-updating rules
Expand All @@ -63,23 +68,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added auth command: manages Safety CLI’s authentication in development environments, allowing easy authentication via the browser.
- auth login - adds ability to authenticate safety cli via the browser
- auth register - adds ability to register for a Safety account via the CLI, and get scanning within minutes
- auth status -
- auth logout -
- `safety check` command can still be used with the API key --key argument, and scan and system-scan commands should also be
- auth status -
- auth logout -
- `safety check` command can still be used with the API key --key argument, and scan and system-scan commands should also be
- Added configure command: configures safety cli using a config.ini file, either saved to the user settings or system settings. This can be used to configure safety’s authentication methods and global proxy details.
- Added system-scan command (beta): Adds the system-scan command, which scans a machine for Python files and environments, reporting these to screen output. system-scan is an experimental beta feature that can scan an entire drive or machine for Python dependency files and Python virtual environments, reporting on packages found and their associated security vulnerabilities.
- Added check-updates command: Check for version updates to Safety CLI, and supports screen and JSON format outputs. Can be used in organizations to test and rollout new version updates as recommended by Safety Cybersecurity.

### New policy file schema for scan and system-scan commands
- New policy file schema to support safety scan and safety system-scan.
Adds scanning-settings root property, which contains settings to configure rules and settings for how safety traverses the directory and subdirectories being scanned, including “exclude” rules, “include” rules, the max directory depth to scan and which root directories safety system-scan should start from.
- Adds report root property, which defines which vulnerability findings safety should auto-ignore (exclude) in its reporting. Supports excluding vulnerability IDs manually, as well as vulnerability groups to ignore based on CVSS severity score.
- Adds report root property, which defines which vulnerability findings safety should auto-ignore (exclude) in its reporting. Supports excluding vulnerability IDs manually, as well as vulnerability groups to ignore based on CVSS severity score.
- Adds new fail-scan-with-exit-code root property, which defines when safety should exit with a failing exit code. This separates safety’s reporting rules from its failing exit code rules, which is a departure from Safety 2.x which had combined rulesets for these. Failing exit codes can be configured based on CVSS severity score.
- Note that the old `safety check` command still supports and relies on the policy schema from safety 2.3.5 and below, meaning no changes are required when migrating to safety 2.x to Safety 3.0.0 when only using the `safety check` command.

### New global options and configurations
- Added global --stage option, to set the development lifecycle stage for the `scan` and `system-scan` commands.
- Added global --key option, to set a Safety API key for any command, including scan, system-scan and check.
- Added global --stage option, to set the development lifecycle stage for the `scan` and `system-scan` commands.
- Added global --key option, to set a Safety API key for any command, including scan, system-scan and check.

### Other
- Safety now requires Python>=3.7. Python 3.7 doesn't have active security support from the Python foundation, and we recommend upgrading to at least Python >= 3.8 whenever possible. Safety’s 3.0.0 Docker image can still be used to scan and secure all Python projects, regardless of Python version. Refer to our [Documentation](https://docs.safetycli.com) for details.
Expand Down
2 changes: 1 addition & 1 deletion safety/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.3
3.2.4
56 changes: 34 additions & 22 deletions safety/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,41 @@
from typing_extensions import Annotated


LOG = logging.getLogger(__name__)


def configure_logger(ctx, param, debug):

LOG = logging.getLogger(__name__)

def configure_logger(ctx, param, value):
level = logging.CRITICAL

if debug:
if value:
level = logging.DEBUG
logging.basicConfig(format='%(asctime)s %(name)s => %(message)s', level=level)
return value

logging.basicConfig(format='%(asctime)s %(name)s => %(message)s', level=level)
def preprocess_args(f):
if '--debug' in sys.argv:
index = sys.argv.index('--debug')
if len(sys.argv) > index + 1:
next_arg = sys.argv[index + 1]
if next_arg in ('1', 'true'):
sys.argv.pop(index + 1) # Remove the next argument (1 or true)
return f

@click.group(cls=SafetyCLILegacyGroup, help=CLI_MAIN_INTRODUCTION, epilog=DEFAULT_EPILOG)
@auth_options()
@proxy_options
@click.option('--disable-optional-telemetry', default=False, is_flag=True, show_default=True, help=CLI_DISABLE_OPTIONAL_TELEMETRY_DATA_HELP)
@click.option('--debug', default=False, help=CLI_DEBUG_HELP, callback=configure_logger)
@click.option('--debug', is_flag=True, help=CLI_DEBUG_HELP, callback=configure_logger)
@click.version_option(version=get_safety_version())
@click.pass_context
@inject_session
@preprocess_args
def cli(ctx, debug, disable_optional_telemetry):
"""
Scan and secure Python projects against package vulnerabilities. To get started navigate to a Python project and run `safety scan`.
"""

SafetyContext().safety_source = 'cli'
telemetry = not disable_optional_telemetry
ctx.obj.config = ConfigModel(telemetry_enabled=telemetry)
Expand Down Expand Up @@ -107,7 +119,7 @@ def inner(ctx, *args, **kwargs):
kwargs.pop('proxy_protocol', None)
kwargs.pop('proxy_host', None)
kwargs.pop('proxy_port', None)

if ctx.get_parameter_source("json_version") != click.core.ParameterSource.DEFAULT and not (
save_json or json or output == 'json'):
raise click.UsageError(
Expand All @@ -128,8 +140,8 @@ def inner(ctx, *args, **kwargs):
proxy_dictionary=None)
audit_and_monitor = (audit_and_monitor and server_audit_and_monitor)

kwargs.update({"auto_remediation_limit": auto_remediation_limit,
"policy_file":policy_file,
kwargs.update({"auto_remediation_limit": auto_remediation_limit,
"policy_file":policy_file,
"audit_and_monitor": audit_and_monitor})

except SafetyError as e:
Expand Down Expand Up @@ -441,18 +453,18 @@ def validate(ctx, name, version, path):
if not os.path.exists(path):
click.secho(f'The path "{path}" does not exist.', fg='red', file=sys.stderr)
sys.exit(EXIT_CODE_FAILURE)

if version not in ["3.0", "2.0", None]:
click.secho(f'Version "{version}" is not a valid value, allowed values are 3.0 and 2.0. Use --path to specify the target file.', fg='red', file=sys.stderr)
sys.exit(EXIT_CODE_FAILURE)

def fail_validation(e):
click.secho(str(e).lstrip(), fg='red', file=sys.stderr)
sys.exit(EXIT_CODE_FAILURE)

if not version:
version = "3.0"

result = ""

if version == "3.0":
Expand All @@ -463,7 +475,7 @@ def fail_validation(e):
policy = load_policy_file(Path(path))
except Exception as e:
fail_validation(e)

click.secho(f"The Safety policy ({version}) file " \
"(Used for scan and system-scan commands) " \
"was successfully parsed " \
Expand All @@ -478,18 +490,18 @@ def fail_validation(e):
sys.exit(EXIT_CODE_FAILURE)

del values['raw']

result = json.dumps(values, indent=4, default=str)

click.secho("The Safety policy file " \
"(Valid only for the check command) " \
"was successfully parsed with the " \
"following values:", fg="green")

console.print_json(result)


@cli.command(cls=SafetyCLILegacyCommand,
@cli.command(cls=SafetyCLILegacyCommand,
help=CLI_CONFIGURE_HELP,
utility_command=True)
@click.option("--proxy-protocol", "-pr", type=click.Choice(['http', 'https']), default='https', cls=DependentOption,
Expand Down Expand Up @@ -519,8 +531,8 @@ def fail_validation(e):
@click.option("--save-to-system/--save-to-user", default=False, is_flag=True,
help=CLI_CONFIGURE_SAVE_TO_SYSTEM)
@click.pass_context
def configure(ctx, proxy_protocol, proxy_host, proxy_port, proxy_timeout,
proxy_required, organization_id, organization_name, stage,
def configure(ctx, proxy_protocol, proxy_host, proxy_port, proxy_timeout,
proxy_required, organization_id, organization_name, stage,
save_to_system):
"""
Configure global settings, like proxy settings and organization details
Expand Down Expand Up @@ -565,7 +577,7 @@ def configure(ctx, proxy_protocol, proxy_host, proxy_port, proxy_timeout,
'host': proxy_host,
'port': str(proxy_port)
})

if not config.has_section(PROXY_SECTION_NAME):
config.add_section(PROXY_SECTION_NAME)

Expand Down Expand Up @@ -669,7 +681,7 @@ def check_updates(ctx: typer.Context,

if not data:
raise SafetyException("No data found.")

console.print("[green]Safety CLI is authenticated:[/green]")

from rich.padding import Padding
Expand All @@ -696,7 +708,7 @@ def check_updates(ctx: typer.Context,
f"If Safety was installed from a requirements file, update Safety to version {latest_available_version} in that requirements file."
)
console.print()
# `pip -i <source_url> install safety=={latest_available_version}` OR
# `pip -i <source_url> install safety=={latest_available_version}` OR
console.print(f"Pip: To install the updated version of Safety directly via pip, run: `pip install safety=={latest_available_version}`")

if console.quiet:
Expand All @@ -717,5 +729,5 @@ def check_updates(ctx: typer.Context,

cli.add_command(alert)

if __name__ == "__main__":
if __name__ == "__main__":
cli()
Loading

0 comments on commit a76bc42

Please sign in to comment.