def test_perform_indexing_v2_only(next_token, expected_next_token, initialized_db): def layer_analyzer(*args, **kwargs): return Mock() with patch("util.secscan.analyzer.LayerAnalyzer", layer_analyzer): secscan_model.configure(app, instance_keys, storage) assert secscan_model.perform_indexing(next_token) == expected_next_token
def test_load_security_information_v2_only(repository, v4_whitelist, initialized_db): app.config["SECURITY_SCANNER_V4_NAMESPACE_WHITELIST"] = v4_whitelist secscan_model.configure(app, instance_keys, storage) repo = registry_model.lookup_repository(*repository) for tag in registry_model.list_all_active_repository_tags(repo): manifest = registry_model.get_manifest_for_tag(tag) assert manifest result = secscan_model.load_security_information(manifest, True) assert isinstance(result, SecurityInformationLookupResult) assert result.status == ScanLookupStatus.NOT_YET_INDEXED
def test_load_security_information(repository, v4_whitelist, initialized_db): app.config["SECURITY_SCANNER_V4_NAMESPACE_WHITELIST"] = v4_whitelist app.config["SECURITY_SCANNER_V4_ENDPOINT"] = "http://clairv4:6060" secscan_api = Mock() with patch("data.secscan_model.secscan_v4_model.ClairSecurityScannerAPI", secscan_api): secscan_model.configure(app, instance_keys, storage) repo = registry_model.lookup_repository(*repository) for tag in registry_model.list_all_active_repository_tags(repo): manifest = registry_model.get_manifest_for_tag(tag) assert manifest result = secscan_model.load_security_information(manifest, True) assert isinstance(result, SecurityInformationLookupResult) assert result.status == ScanLookupStatus.NOT_YET_INDEXED
def test_perform_indexing(next_token, expected_next_token, initialized_db): app.config["SECURITY_SCANNER_V4_NAMESPACE_WHITELIST"] = ["devtable"] app.config["SECURITY_SCANNER_V4_ENDPOINT"] = "http://clairv4:6060" def secscan_api(*args, **kwargs): api = Mock() api.state.return_value = {"state": "abc"} api.index.return_value = ({"err": None, "state": IndexReportState.Index_Finished}, "abc") return api def layer_analyzer(*args, **kwargs): return Mock() with patch("data.secscan_model.secscan_v4_model.ClairSecurityScannerAPI", secscan_api): with patch("util.secscan.analyzer.LayerAnalyzer", layer_analyzer): secscan_model.configure(app, instance_keys, storage) assert secscan_model.perform_indexing(next_token) == expected_next_token
def test_perform_indexing(next_token, expected_next_token, expected_error, initialized_db): app.config["SECURITY_SCANNER_V4_ENDPOINT"] = "http://clairv4:6060" def secscan_api(*args, **kwargs): api = Mock() api.state.return_value = {"state": "abc"} api.index.return_value = ({ "err": None, "state": IndexReportState.Index_Finished }, "abc") return api with patch("data.secscan_model.secscan_v4_model.ClairSecurityScannerAPI", secscan_api): secscan_model.configure(app, instance_keys, storage) if expected_error is not None: with pytest.raises(expected_error): secscan_model.perform_indexing(next_token) else: assert secscan_model.perform_indexing( next_token) == expected_next_token
def test_load_security_information(indexed_v2, indexed_v4, expected_status, initialized_db): secscan_model.configure(app, instance_keys, storage) repository_ref = registry_model.lookup_repository("devtable", "simple") tag = registry_model.find_matching_tag(repository_ref, ["latest"]) manifest = registry_model.get_manifest_for_tag(tag) assert manifest registry_model.populate_legacy_images_for_testing(manifest, storage) image = shared.get_legacy_image_for_manifest(manifest._db_id) if indexed_v2: image.security_indexed = False image.security_indexed_engine = 3 image.save() else: ManifestLegacyImage.delete().where( ManifestLegacyImage.manifest == manifest._db_id).execute() if indexed_v4: ManifestSecurityStatus.create( manifest=manifest._db_id, repository=repository_ref._db_id, error_json={}, index_status=IndexStatus.MANIFEST_UNSUPPORTED, indexer_hash="abc", indexer_version=IndexerVersion.V4, metadata_json={}, ) result = secscan_model.load_security_information(manifest, True) assert isinstance(result, SecurityInformationLookupResult) assert result.status == expected_status
_v2_key_path = os.path.join(OVERRIDE_CONFIG_DIRECTORY, DOCKER_V2_SIGNINGKEY_FILENAME) if os.path.exists(_v2_key_path): docker_v2_signing_key = RSAKey().load(_v2_key_path) else: docker_v2_signing_key = RSAKey(key=RSA.generate(2048)) # Configure the database. if app.config.get("DATABASE_SECRET_KEY") is None and app.config.get("SETUP_COMPLETE", False): raise Exception("Missing DATABASE_SECRET_KEY in config; did you perhaps forget to add it?") database.configure(app.config) model.config.app_config = app.config model.config.store = storage model.config.register_repo_cleanup_callback(tuf_metadata_api.delete_metadata) secscan_model.configure(app, instance_keys, storage) secscan_model.register_model_cleanup_callbacks(model.config) logs_model.configure(app.config) @login_manager.user_loader def load_user(user_uuid): logger.debug("User loader loading deferred user with uuid: %s", user_uuid) return LoginWrappedDBUser(user_uuid) get_app_url = partial(get_app_url, app.config)
def test_notification(issue, initialized_db): worker = SecurityScanningNotificationWorker(secscan_notification_queue) secscan_model.configure(app, instance_keys, storage) worker._secscan_model = secscan_model hostname = urlparse(app.config["SECURITY_SCANNER_V4_ENDPOINT"]).netloc with fake_security_scanner(hostname=hostname) as fake: repository_ref = registry_model.lookup_repository("devtable", "simple") # Add a security notification event to the repository. if issue != "no_event_registered": model.notification.create_repo_notification( repository_ref.id, "vulnerability_found", "webhook", {}, { "vulnerability": { "priority": "Low" if issue != "severity_too_low" else "Critical", }, }, ) tag = registry_model.get_repo_tag(repository_ref, "latest") manifest = registry_model.get_manifest_for_tag(tag) # Add a notification to the scanner, matching the manifest. notification_id = "somenotificationid" fake.add_notification( notification_id if issue != "wrong_id" else "wrongid", manifest.digest if issue != "no_matching_manifest" else "sha256:incorrect", "added", { "normalized_severity": "High", "description": "Some description", "package": { "id": "42", "name": "FooBar", "version": "v0.0.1", }, "name": "BarBaz", "links": "http://example.com", }, ) # Add the notification to the queue. name = ["with_id", notification_id] secscan_notification_queue.put( name, json.dumps({"notification_id": notification_id}), ) # Process the notification via the worker. worker.poll_queue() # Ensure the repository notification was enqueued. found = notification_queue.get() if issue: assert found is None return assert found is not None body = json.loads(found["body"]) assert body["event_data"]["repository"] == "devtable/simple" assert body["event_data"]["namespace"] == "devtable" assert body["event_data"]["name"] == "simple" assert body["event_data"]["tags"] == ["latest"] assert body["event_data"]["vulnerability"]["id"] == "BarBaz" assert body["event_data"]["vulnerability"]["description"] == "Some description" assert body["event_data"]["vulnerability"]["priority"] == "High"