def test_repositories_added_can_be_scanned(self, mock_rootdir,
                                               repo_to_scan):
        directory = '{}/repos/{}'.format(
            mock_rootdir,
            BaseStorage.hash_filename('Yelp/detect-secrets'),
        )
        mocked_sha = 'aabbcc'

        # We don't **actually** want to clone the repo per test run.
        with mock_git_calls(
                SubprocessMock(expected_input=(
                    'git clone https://github.com/Yelp/detect-secrets {} --bare'
                ).format(directory, ), ),
                # Since there is no prior sha to retrieve
                SubprocessMock(
                    expected_input='git rev-parse HEAD',
                    mocked_output=mocked_sha,
                )):
            assert main([
                'add',
                'https://github.com/Yelp/detect-secrets',
                '--root-dir',
                mock_rootdir,
            ]) == 0

        with mock_git_calls(
                # Getting latest changes
                SubprocessMock(
                    expected_input='git rev-parse --abbrev-ref HEAD',
                    mocked_output='master',
                ),
                SubprocessMock(
                    expected_input=
                    'git fetch --quiet origin master:master --force', ),
                # Getting relevant diff
                SubprocessMock(
                    expected_input=
                    'git diff {} HEAD --name-only --diff-filter ACM'.format(
                        mocked_sha),
                    mocked_output='filenameA',
                ),
                SubprocessMock(
                    expected_input='git diff {} HEAD -- filenameA'.format(
                        mocked_sha),
                    mocked_output='',
                ),
                # Storing latest sha
                SubprocessMock(expected_input='git rev-parse HEAD', ),
        ):
            assert main([
                'scan',
                repo_to_scan,
                '--root-dir',
                mock_rootdir,
            ]) == 0
示例#2
0
    def test_no_baseline(self, mock_logic, mock_rootdir):
        repo = mock_logic()
        with mock_git_calls(*self.git_calls(mock_rootdir)):
            secrets = repo.scan()

        # It matches both HexHighEntropyString and AWSKeyDetector
        assert len(secrets.data['examples/aws_credentials.json']) == 2
示例#3
0
    def test_add_local_repo(self, mock_file_operations, mock_rootdir):
        # This just needs to exist; no actual operations will be done to this.
        repo = 'examples'

        git_calls = [
            # repo.update
            SubprocessMock(
                expected_input='git rev-parse HEAD',
                mocked_output='mocked_sha',
            ),
        ]

        with mock_git_calls(*git_calls):
            args = self.parse_args(
                'add {} --baseline .secrets.baseline --local --root-dir {}'.
                format(
                    repo,
                    mock_rootdir,
                ))

            add_repo(args)

        mock_file_operations.write.assert_called_with(
            metadata_factory(
                sha='mocked_sha',
                repo=os.path.abspath(
                    os.path.join(
                        os.path.dirname(__file__),
                        '../../examples',
                    ), ),
                baseline_filename='.secrets.baseline',
                json=True,
            ), )
    def test_no_baseline_file_provided(self, mock_logic, mock_rootdir):
        repo = mock_logic(
            baseline_filename=None,
        )
        with mock_git_calls(*self.git_calls(mock_rootdir)[:-1]):
            secrets = repo.scan()

        assert len(secrets.data['examples/aws_credentials.json']) == 3
示例#5
0
        def wrapped_mock_git_calls(git_calls):
            if not git_calls:
                # Need to yield **something**
                yield
                return

            with mock_git_calls(*git_calls):
                yield
    def test_clone_repo_if_exists(self, base_storage, mock_rootdir):
        with assert_directories_created():
            repo = base_storage.setup('[email protected]:yelp/detect-secrets')

        with mock_git_calls(
                self.construct_subprocess_mock_git_clone(
                    repo,
                    b'fatal: destination path \'blah\' already exists',
                    mock_rootdir,
                ), ):
            repo.clone()
 def test_name(self, repo, name, local_storage):
     """OK, I admit this is kinda a lame test case, because technically
     everything is mocked out. However, it's needed for coverage, and
     it *does* test things (kinda).
     """
     with mock_git_calls(
             SubprocessMock(
                 expected_input='git remote get-url origin',
                 mocked_output='[email protected]:yelp/detect-secrets',
             ), ), assert_directories_created():
         assert local_storage.setup(repo).repository_name == name
示例#8
0
    def test_success(self, mock_logic):
        repo = mock_logic()

        with mock_git_calls(
                SubprocessMock(
                    expected_input='git rev-parse HEAD',
                    mocked_output='new_hash',
                )):
            repo.update()

        assert repo.last_commit_hash == 'new_hash'
    def test_clone_repo_something_else_went_wrong(self, mock_rootdir,
                                                  base_storage):
        with assert_directories_created():
            repo = base_storage.setup('[email protected]:yelp/detect-secrets')

        with mock_git_calls(
                self.construct_subprocess_mock_git_clone(
                    repo,
                    b'Some other error message, not expected',
                    mock_rootdir,
                )), pytest.raises(subprocess.CalledProcessError):
            repo.clone()
示例#10
0
    def test_error_when_getting_git_tracked_files(self, path):
        with mock_git_calls(
                'detect_secrets.core.baseline.subprocess.check_output',
            (SubprocessMock(
                expected_input='git -C ./test_data/files ls-files',
                should_throw_exception=True,
                mocked_output='',
            ), ),
        ):
            results = self.get_results(path=['./test_data/files'])

        assert not results
示例#11
0
    def test_no_files_in_git_repo(self):
        with mock_git_calls(
                'detect_secrets.core.baseline.subprocess.check_output',
            (SubprocessMock(
                expected_input='git ls-files will_be_mocked',
                should_throw_exception=True,
                mocked_output='',
            ), ),
        ):
            results = self.get_results(path=['will_be_mocked'])

        assert not results
示例#12
0
    def test_unable_to_find_baseline(self, mock_logic, mock_rootdir):
        calls = self.git_calls(mock_rootdir)
        calls[-1] = SubprocessMock(
            expected_input='git show HEAD:foobar',
            mocked_output=b'fatal: Path \'foobar\' does not exist',
            should_throw_exception=True,
        )

        repo = mock_logic()
        with mock_git_calls(*calls):
            secrets = repo.scan()

        assert len(secrets.data['examples/aws_credentials.json']) == 2
示例#13
0
    def test_no_files_in_git_repo(self):
        with mock_git_calls(
            'detect_secrets.core.baseline.subprocess.check_output',
            (
                SubprocessMock(
                    expected_input='git ls-files will_be_mocked',
                    should_throw_exception=True,
                    mocked_output='',
                ),
            ),
        ):
            results = self.get_results(rootdir='will_be_mocked')

        assert not results
示例#14
0
    def test_quit_if_baseline_is_changed_but_not_staged(self, mock_log):
        with mock_git_calls(
                'detect_secrets.pre_commit_hook.subprocess.check_output',
            (SubprocessMock(
                expected_input='git diff --name-only',
                mocked_output=b'baseline.file',
            ), ),
        ):
            assert_commit_blocked(
                '--baseline baseline.file test_data/files/file_with_secrets.py',
            )

        assert mock_log.error_messages == (
            'Your baseline file (baseline.file) is unstaged.\n'
            '`git add baseline.file` to fix this.\n')
示例#15
0
    def test_scan_nonexistent_last_saved_hash(self, mock_logic, mock_rootdir):
        calls = self.git_calls(mock_rootdir)
        calls[-2] = SubprocessMock(
            expected_input=
            'git diff sha256-hash HEAD -- examples/aws_credentials.json',
            mocked_output=b'fatal: the hash is not in git history',
            should_throw_exception=True,
        )
        calls[-1] = SubprocessMock(expected_input='git rev-parse HEAD', )

        repo = mock_logic()
        with mock_git_calls(*calls):
            secrets = repo.scan()

        assert secrets.data == {}
示例#16
0
    def test_exclude_lines(
        self,
        mock_logic,
        mock_rootdir,
        exclude_lines_regex,
        expected_line_number,
    ):
        repo = mock_logic()
        with mock_git_calls(*self.git_calls(mock_rootdir)):
            secrets = repo.scan(exclude_lines_regex=exclude_lines_regex)

        assert len(secrets.data) == 1
        assert len(secrets.data['examples/aws_credentials.json']) == 1

        for _, secret in secrets.data['examples/aws_credentials.json'].items():
            assert secret.lineno == expected_line_number
    def test_scan_with_baseline(self, mock_logic, mock_rootdir):
        baseline = json.dumps({
            'results': {
                'examples/aws_credentials.json': [
                    {
                        'type': 'Hex High Entropy String',
                        'hashed_secret': '2353d31737bbbdb10eb97466b8f2dc057ead1432',
                        'line_number': 3,       # does not matter
                    },
                    {
                        'type': 'AWS Access Key',
                        'hashed_secret': '25910f981e85ca04baf359199dd0bd4a3ae738b6',
                        'line_number': 3,       # does not matter
                    },
                    {
                        'type': 'IBM COS HMAC Credentials',
                        'hashed_secret': '9c6e0753631454e4ab8d896c242dcf4f8300fd57',
                        'line_number': 3,       # does not matter
                    },
                ],
            },
            'exclude_regex': '',
            'plugins_used': [
                {
                    'hex_limit': 3.5,
                    'name': 'HexHighEntropyString',
                },
                {
                    'name': 'AWSKeyDetector',
                },
                {
                    'name': 'IbmCosHmacDetector',
                },
            ],
        })

        calls = self.git_calls(mock_rootdir)
        calls[-1] = SubprocessMock(
            expected_input='git show HEAD:foobar',
            mocked_output=baseline,
        )

        repo = mock_logic()
        with mock_git_calls(*calls):
            secrets = repo.scan()

        assert len(secrets.data) == 0
    def test_quit_if_baseline_is_changed_but_not_staged(self, mock_log):
        with mock_git_calls(
            'detect_secrets.pre_commit_hook.subprocess.check_output',
            (
                SubprocessMock(
                    expected_input='git diff --name-only',
                    mocked_output=b'baseline.file',
                ),
            ),
        ):
            assert_commit_blocked(
                '--baseline baseline.file test_data/files/file_with_secrets.py',
            )

        assert mock_log.error_messages == (
            'Your baseline file (baseline.file) is unstaged.\n'
            '`git add baseline.file` to fix this.\n'
        )
示例#19
0
    def add_non_local_repo(self, mock_rootdir):
        repo = '[email protected]:yelp/detect-secrets'
        directory = '{}/repos/{}'.format(
            mock_rootdir,
            BaseStorage.hash_filename('yelp/detect-secrets'),
        )

        git_calls = [
            SubprocessMock(expected_input='git clone {} {} --bare'.format(
                repo, directory), ),
            SubprocessMock(
                expected_input='git rev-parse HEAD',
                mocked_output='mocked_sha',
            ),
        ]

        with mock_git_calls(*git_calls):
            args = self.parse_args('add {} --root-dir {}'.format(
                repo, mock_rootdir))
            add_repo(args)
示例#20
0
    def test_add_s3_backend_repo(self, mock_file_operations, mocked_boto):
        args = self.parse_args(
            'add {} '
            '--local '
            '--storage s3 '
            '--s3-credentials-file examples/aws_credentials.json '
            '--s3-bucket pail'.format('examples'),
            has_s3=True,
        )

        git_calls = [
            # repo.update
            SubprocessMock(
                expected_input='git rev-parse HEAD',
                mocked_output='mocked_sha',
            ),
        ]

        with mock_git_calls(*git_calls):
            mocked_boto.list_objects_v2.return_value = {}
            add_repo(args)
示例#21
0
    def test_exclude_files(self, mock_logic, mock_rootdir):
        repo = mock_logic()
        with mock_git_calls(*self.git_calls(mock_rootdir)):
            secrets = repo.scan(exclude_files_regex=r'aws_credentials.json$')

        assert 'examples/aws_credentials.json' not in secrets.data
 def test_clone(self, local_storage):
     # We're asserting that nothing is run in this case.
     with mock_git_calls(), assert_directories_created():
         local_storage.setup('[email protected]:yelp/detect-secrets')\
             .clone()