Esempio n. 1
0
    def test_saves_to_baseline():
        # We create an empty baseline, with customized settings.
        # This way, we expect the engine to use the settings configured by the baseline,
        # but have the results replaced by the new scan.
        with transient_settings({
                'plugins_used': [
                    {
                        'name': 'Base64HighEntropyString',
                        'limit': 4.5,
                    },
                ],
        }):
            secrets = SecretsCollection()
            old_secrets = baseline.format_for_output(secrets)

        with mock_printer(
                main_module) as printer, tempfile.NamedTemporaryFile() as f:
            baseline.save_to_file(old_secrets, f.name)
            f.seek(0)

            # We also test setting the root directory through this test.
            main_module.main(['scan', 'test_data', '--baseline', f.name])

            f.seek(0)
            new_secrets = json.loads(f.read())
            assert not secrets.exactly_equals(
                baseline.load(new_secrets, f.name))
            assert new_secrets['plugins_used'] == [
                {
                    'name': 'Base64HighEntropyString',
                    'limit': 4.5,
                },
            ]
            assert not printer.message
Esempio n. 2
0
def test_baseline(printer) -> SecretsCollection:
    # We call this through the CLI so it does the plugin initialization for us.
    # It doesn't matter what we scan -- we just need a large enough corpus so that
    # we can perform our tests.
    main(['scan', 'test_data'])
    output = printer.message
    printer.clear()

    return baseline.load(json.loads(output), 'does-not-matter')
Esempio n. 3
0
def test_load_and_output():
    with open('.secrets.baseline') as f:
        data = json.loads(f.read())

    secrets = baseline.load(data, filename='.secrets.baseline')
    output = baseline.format_for_output(secrets)

    for item in [data, output]:
        item.pop('generated_at')

    # We perform string matching because we want to ensure stable sorts.
    assert json.dumps(output) == json.dumps(data)

    # We need to make sure that default values carry through, for future backwards compatibility.
    for plugin in output['plugins_used']:
        if plugin['name'] == 'Base64HighEntropyString':
            assert plugin['limit'] == 4.5
            break
Esempio n. 4
0
def test_fails_if_no_line_numbers_found(printer):
    with transient_settings({
            'plugins_used': [
                {
                    'name': 'Base64HighEntropyString'
                },
            ],
    }):
        secrets = SecretsCollection()
        secrets.scan_file('test_data/config.env')

    # Remove line numbers
    secrets = baseline.load(
        baseline.format_for_output(secrets, is_slim_mode=True))

    with mock.patch('detect_secrets.audit.io.clear_screen') as m:
        run_logic(secrets)
        assert not m.called

    assert 'No line numbers found in baseline' in printer.message
Esempio n. 5
0
    def test_restores_line_numbers():
        with tempfile.NamedTemporaryFile('w+') as f:
            with redirect_stdout(f):
                main_module.main(['scan', '--slim', 'test_data/config.env'])

            f.seek(0)
            main_module.main([
                'scan',
                '--slim', 'test_data/config.md', 'test_data/config.env',
                '--baseline', f.name,
            ])

            f.seek(0)
            secrets = baseline.load(baseline.load_from_file(f.name))

        # Make sure both old and new files exist
        assert secrets.files == {'test_data/config.env', 'test_data/config.md'}

        # Make sure they both have line numbers
        assert list(secrets['test_data/config.env'])[0].line_number
        assert list(secrets['test_data/config.md'])[0].line_number
Esempio n. 6
0
def run_logic(
    secrets: SecretsCollection,
    input: Optional[str] = None,
) -> SecretsCollection:
    """
    :param input: if provided, will automatically quit at the end of input string.
        otherwise, will assert that no user input is requested.
    """
    with tempfile.NamedTemporaryFile() as f:
        baseline.save_to_file(secrets, f.name)
        f.seek(0)

        with mock.patch('detect_secrets.audit.io.input') as m:
            if input is not None:
                m.side_effect = list(input) + ['q']

            main(['audit', f.name])

            if input is None:
                assert not m.called

        return baseline.load(baseline.load_from_file(f.name), f.name)