From e784adaa1fb7cbf785d3b0f1a83516bc02ba5b8a Mon Sep 17 00:00:00 2001 From: Holly Gong Date: Mon, 16 Dec 2024 17:04:03 +1100 Subject: [PATCH 1/3] feat(api): initial commit for adding linter API --- gcp/api/osv_service_v1_pb2.py | 73 +++++++++++---------- gcp/api/osv_service_v1_pb2.pyi | 36 +++++++++++ gcp/api/osv_service_v1_pb2_grpc.py | 44 +++++++++++++ gcp/api/server.py | 27 ++++++++ gcp/api/v1/api_descriptor.pb | Bin 112887 -> 115682 bytes gcp/api/v1/osv_service_v1.proto | 18 ++++++ osv/build_protos.sh | 2 +- osv/importfinding.proto | 42 ++++++++++++ osv/importfinding_pb2.py | 29 +++++++++ osv/importfinding_pb2.pyi | 99 +++++++++++++++++++++++++++++ osv/vulnerability_pb2.py | 6 +- 11 files changed, 339 insertions(+), 37 deletions(-) create mode 100644 osv/importfinding.proto create mode 100644 osv/importfinding_pb2.py create mode 100644 osv/importfinding_pb2.pyi diff --git a/gcp/api/osv_service_v1_pb2.py b/gcp/api/osv_service_v1_pb2.py index b8d6466bc11..af8f1c26fa5 100644 --- a/gcp/api/osv_service_v1_pb2.py +++ b/gcp/api/osv_service_v1_pb2.py @@ -13,10 +13,11 @@ from osv import vulnerability_pb2 as osv_dot_vulnerability__pb2 +from osv import importfinding_pb2 as osv_dot_importfinding__pb2 from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14osv_service_v1.proto\x12\x06osv.v1\x1a\x17osv/vulnerability.proto\x1a\x1cgoogle/api/annotations.proto\"O\n\x11VulnerabilityList\x12!\n\x05vulns\x18\x01 \x03(\x0b\x32\x12.osv.Vulnerability\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\"D\n\x16\x42\x61tchVulnerabilityList\x12*\n\x07results\x18\x01 \x03(\x0b\x32\x19.osv.v1.VulnerabilityList\"h\n\x05Query\x12\x10\n\x06\x63ommit\x18\x01 \x01(\tH\x00\x12\x11\n\x07version\x18\x02 \x01(\tH\x00\x12\x1d\n\x07package\x18\x04 \x01(\x0b\x32\x0c.osv.Package\x12\x12\n\npage_token\x18\x05 \x01(\tB\x07\n\x05param\",\n\nBatchQuery\x12\x1e\n\x07queries\x18\x01 \x03(\x0b\x32\r.osv.v1.Query\"#\n\x15GetVulnByIdParameters\x12\n\n\x02id\x18\x01 \x01(\t\"7\n\x17QueryAffectedParameters\x12\x1c\n\x05query\x18\x01 \x01(\x0b\x32\r.osv.v1.Query\"A\n\x1cQueryAffectedBatchParameters\x12!\n\x05query\x18\x01 \x01(\x0b\x32\x12.osv.v1.BatchQuery\"A\n\x1a\x44\x65termineVersionParameters\x12#\n\x05query\x18\x01 \x01(\x0b\x32\x14.osv.v1.VersionQuery\"C\n\x0cVersionQuery\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x0b\x66ile_hashes\x18\x02 \x03(\x0b\x32\x10.osv.v1.FileHash\"n\n\x08\x46ileHash\x12\x11\n\tfile_path\x18\x01 \x01(\t\x12,\n\thash_type\x18\x02 \x01(\x0e\x32\x19.osv.v1.FileHash.HashType\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\"\x13\n\x08HashType\x12\x07\n\x03MD5\x10\x00\"9\n\x10VersionMatchList\x12%\n\x07matches\x18\x01 \x03(\x0b\x32\x14.osv.v1.VersionMatch\"\xc7\x01\n\x0cVersionMatch\x12\r\n\x05score\x18\x01 \x01(\x01\x12\x37\n\trepo_info\x18\x02 \x01(\x0b\x32$.osv.v1.VersionRepositoryInformation\x12$\n\x0eosv_identifier\x18\x03 \x01(\x0b\x32\x0c.osv.Package\x12\r\n\x05\x63pe23\x18\x05 \x01(\t\x12\x1c\n\x14minimum_file_matches\x18\x06 \x01(\x03\x12\x1c\n\x14\x65stimated_diff_files\x18\x07 \x01(\x03\"\xc0\x01\n\x1cVersionRepositoryInformation\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.osv.v1.VersionRepositoryInformation.RepoType\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x0b\n\x03tag\x18\x04 \x01(\t\x12\x0f\n\x07version\x18\x05 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x06 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x32\xc5\x03\n\x03OSV\x12X\n\x0bGetVulnById\x12\x1d.osv.v1.GetVulnByIdParameters\x1a\x12.osv.Vulnerability\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/vulns/{id}\x12\x65\n\rQueryAffected\x12\x1f.osv.v1.QueryAffectedParameters\x1a\x19.osv.v1.VulnerabilityList\"\x18\x82\xd3\xe4\x93\x02\x12\"\t/v1/query:\x05query\x12y\n\x12QueryAffectedBatch\x12$.osv.v1.QueryAffectedBatchParameters\x1a\x1e.osv.v1.BatchVulnerabilityList\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x0e/v1/querybatch:\x05query\x12\x81\x01\n\x10\x44\x65termineVersion\x12\".osv.v1.DetermineVersionParameters\x1a\x18.osv.v1.VersionMatchList\"/\x82\xd3\xe4\x93\x02)\" /v1experimental/determineversion:\x05queryb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14osv_service_v1.proto\x12\x06osv.v1\x1a\x17osv/vulnerability.proto\x1a\x17osv/importfinding.proto\x1a\x1cgoogle/api/annotations.proto\"O\n\x11VulnerabilityList\x12!\n\x05vulns\x18\x01 \x03(\x0b\x32\x12.osv.Vulnerability\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\"D\n\x16\x42\x61tchVulnerabilityList\x12*\n\x07results\x18\x01 \x03(\x0b\x32\x19.osv.v1.VulnerabilityList\"h\n\x05Query\x12\x10\n\x06\x63ommit\x18\x01 \x01(\tH\x00\x12\x11\n\x07version\x18\x02 \x01(\tH\x00\x12\x1d\n\x07package\x18\x04 \x01(\x0b\x32\x0c.osv.Package\x12\x12\n\npage_token\x18\x05 \x01(\tB\x07\n\x05param\",\n\nBatchQuery\x12\x1e\n\x07queries\x18\x01 \x03(\x0b\x32\r.osv.v1.Query\"#\n\x15GetVulnByIdParameters\x12\n\n\x02id\x18\x01 \x01(\t\"7\n\x17QueryAffectedParameters\x12\x1c\n\x05query\x18\x01 \x01(\x0b\x32\r.osv.v1.Query\"A\n\x1cQueryAffectedBatchParameters\x12!\n\x05query\x18\x01 \x01(\x0b\x32\x12.osv.v1.BatchQuery\"A\n\x1a\x44\x65termineVersionParameters\x12#\n\x05query\x18\x01 \x01(\x0b\x32\x14.osv.v1.VersionQuery\"*\n\x18ImportFindingsParameters\x12\x0e\n\x06source\x18\x01 \x01(\t\"C\n\x0cVersionQuery\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x0b\x66ile_hashes\x18\x02 \x03(\x0b\x32\x10.osv.v1.FileHash\"n\n\x08\x46ileHash\x12\x11\n\tfile_path\x18\x01 \x01(\t\x12,\n\thash_type\x18\x02 \x01(\x0e\x32\x19.osv.v1.FileHash.HashType\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\"\x13\n\x08HashType\x12\x07\n\x03MD5\x10\x00\"9\n\x10VersionMatchList\x12%\n\x07matches\x18\x01 \x03(\x0b\x32\x14.osv.v1.VersionMatch\"@\n\x11ImportFindingList\x12+\n\x0finvalid_records\x18\x01 \x03(\x0b\x32\x12.osv.ImportFinding\"\xc7\x01\n\x0cVersionMatch\x12\r\n\x05score\x18\x01 \x01(\x01\x12\x37\n\trepo_info\x18\x02 \x01(\x0b\x32$.osv.v1.VersionRepositoryInformation\x12$\n\x0eosv_identifier\x18\x03 \x01(\x0b\x32\x0c.osv.Package\x12\r\n\x05\x63pe23\x18\x05 \x01(\t\x12\x1c\n\x14minimum_file_matches\x18\x06 \x01(\x03\x12\x1c\n\x14\x65stimated_diff_files\x18\x07 \x01(\x03\"\xc0\x01\n\x1cVersionRepositoryInformation\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.osv.v1.VersionRepositoryInformation.RepoType\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x0b\n\x03tag\x18\x04 \x01(\t\x12\x0f\n\x07version\x18\x05 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x06 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x32\xb9\x04\n\x03OSV\x12X\n\x0bGetVulnById\x12\x1d.osv.v1.GetVulnByIdParameters\x1a\x12.osv.Vulnerability\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/vulns/{id}\x12\x65\n\rQueryAffected\x12\x1f.osv.v1.QueryAffectedParameters\x1a\x19.osv.v1.VulnerabilityList\"\x18\x82\xd3\xe4\x93\x02\x12\"\t/v1/query:\x05query\x12y\n\x12QueryAffectedBatch\x12$.osv.v1.QueryAffectedBatchParameters\x1a\x1e.osv.v1.BatchVulnerabilityList\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x0e/v1/querybatch:\x05query\x12\x81\x01\n\x10\x44\x65termineVersion\x12\".osv.v1.DetermineVersionParameters\x1a\x18.osv.v1.VersionMatchList\"/\x82\xd3\xe4\x93\x02)\" /v1experimental/determineversion:\x05query\x12r\n\x0eImportFindings\x12 .osv.v1.ImportFindingsParameters\x1a\x19.osv.v1.ImportFindingList\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/v1/importfindings/{source}b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,36 +32,42 @@ _globals['_OSV'].methods_by_name['QueryAffectedBatch']._serialized_options = b'\202\323\344\223\002\027\"\016/v1/querybatch:\005query' _globals['_OSV'].methods_by_name['DetermineVersion']._loaded_options = None _globals['_OSV'].methods_by_name['DetermineVersion']._serialized_options = b'\202\323\344\223\002)\" /v1experimental/determineversion:\005query' - _globals['_VULNERABILITYLIST']._serialized_start=87 - _globals['_VULNERABILITYLIST']._serialized_end=166 - _globals['_BATCHVULNERABILITYLIST']._serialized_start=168 - _globals['_BATCHVULNERABILITYLIST']._serialized_end=236 - _globals['_QUERY']._serialized_start=238 - _globals['_QUERY']._serialized_end=342 - _globals['_BATCHQUERY']._serialized_start=344 - _globals['_BATCHQUERY']._serialized_end=388 - _globals['_GETVULNBYIDPARAMETERS']._serialized_start=390 - _globals['_GETVULNBYIDPARAMETERS']._serialized_end=425 - _globals['_QUERYAFFECTEDPARAMETERS']._serialized_start=427 - _globals['_QUERYAFFECTEDPARAMETERS']._serialized_end=482 - _globals['_QUERYAFFECTEDBATCHPARAMETERS']._serialized_start=484 - _globals['_QUERYAFFECTEDBATCHPARAMETERS']._serialized_end=549 - _globals['_DETERMINEVERSIONPARAMETERS']._serialized_start=551 - _globals['_DETERMINEVERSIONPARAMETERS']._serialized_end=616 - _globals['_VERSIONQUERY']._serialized_start=618 - _globals['_VERSIONQUERY']._serialized_end=685 - _globals['_FILEHASH']._serialized_start=687 - _globals['_FILEHASH']._serialized_end=797 - _globals['_FILEHASH_HASHTYPE']._serialized_start=778 - _globals['_FILEHASH_HASHTYPE']._serialized_end=797 - _globals['_VERSIONMATCHLIST']._serialized_start=799 - _globals['_VERSIONMATCHLIST']._serialized_end=856 - _globals['_VERSIONMATCH']._serialized_start=859 - _globals['_VERSIONMATCH']._serialized_end=1058 - _globals['_VERSIONREPOSITORYINFORMATION']._serialized_start=1061 - _globals['_VERSIONREPOSITORYINFORMATION']._serialized_end=1253 - _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_start=1217 - _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_end=1253 - _globals['_OSV']._serialized_start=1256 - _globals['_OSV']._serialized_end=1709 + _globals['_OSV'].methods_by_name['ImportFindings']._loaded_options = None + _globals['_OSV'].methods_by_name['ImportFindings']._serialized_options = b'\202\323\344\223\002\035\022\033/v1/importfindings/{source}' + _globals['_VULNERABILITYLIST']._serialized_start=112 + _globals['_VULNERABILITYLIST']._serialized_end=191 + _globals['_BATCHVULNERABILITYLIST']._serialized_start=193 + _globals['_BATCHVULNERABILITYLIST']._serialized_end=261 + _globals['_QUERY']._serialized_start=263 + _globals['_QUERY']._serialized_end=367 + _globals['_BATCHQUERY']._serialized_start=369 + _globals['_BATCHQUERY']._serialized_end=413 + _globals['_GETVULNBYIDPARAMETERS']._serialized_start=415 + _globals['_GETVULNBYIDPARAMETERS']._serialized_end=450 + _globals['_QUERYAFFECTEDPARAMETERS']._serialized_start=452 + _globals['_QUERYAFFECTEDPARAMETERS']._serialized_end=507 + _globals['_QUERYAFFECTEDBATCHPARAMETERS']._serialized_start=509 + _globals['_QUERYAFFECTEDBATCHPARAMETERS']._serialized_end=574 + _globals['_DETERMINEVERSIONPARAMETERS']._serialized_start=576 + _globals['_DETERMINEVERSIONPARAMETERS']._serialized_end=641 + _globals['_IMPORTFINDINGSPARAMETERS']._serialized_start=643 + _globals['_IMPORTFINDINGSPARAMETERS']._serialized_end=685 + _globals['_VERSIONQUERY']._serialized_start=687 + _globals['_VERSIONQUERY']._serialized_end=754 + _globals['_FILEHASH']._serialized_start=756 + _globals['_FILEHASH']._serialized_end=866 + _globals['_FILEHASH_HASHTYPE']._serialized_start=847 + _globals['_FILEHASH_HASHTYPE']._serialized_end=866 + _globals['_VERSIONMATCHLIST']._serialized_start=868 + _globals['_VERSIONMATCHLIST']._serialized_end=925 + _globals['_IMPORTFINDINGLIST']._serialized_start=927 + _globals['_IMPORTFINDINGLIST']._serialized_end=991 + _globals['_VERSIONMATCH']._serialized_start=994 + _globals['_VERSIONMATCH']._serialized_end=1193 + _globals['_VERSIONREPOSITORYINFORMATION']._serialized_start=1196 + _globals['_VERSIONREPOSITORYINFORMATION']._serialized_end=1388 + _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_start=1352 + _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_end=1388 + _globals['_OSV']._serialized_start=1391 + _globals['_OSV']._serialized_end=1960 # @@protoc_insertion_point(module_scope) diff --git a/gcp/api/osv_service_v1_pb2.pyi b/gcp/api/osv_service_v1_pb2.pyi index fcaa5899dc5..a8e58762f05 100644 --- a/gcp/api/osv_service_v1_pb2.pyi +++ b/gcp/api/osv_service_v1_pb2.pyi @@ -22,6 +22,7 @@ import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message +import osv.importfinding_pb2 import osv.vulnerability_pb2 import sys import typing @@ -203,6 +204,23 @@ class DetermineVersionParameters(google.protobuf.message.Message): global___DetermineVersionParameters = DetermineVersionParameters +@typing.final +class ImportFindingsParameters(google.protobuf.message.Message): + """Parameters for ImportFindings.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SOURCE_FIELD_NUMBER: builtins.int + source: builtins.str + def __init__( + self, + *, + source: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["source", b"source"]) -> None: ... + +global___ImportFindingsParameters = ImportFindingsParameters + @typing.final class VersionQuery(google.protobuf.message.Message): """The version query.""" @@ -280,6 +298,24 @@ class VersionMatchList(google.protobuf.message.Message): global___VersionMatchList = VersionMatchList +@typing.final +class ImportFindingList(google.protobuf.message.Message): + """Result of ImportFindings.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INVALID_RECORDS_FIELD_NUMBER: builtins.int + @property + def invalid_records(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[osv.importfinding_pb2.ImportFinding]: ... + def __init__( + self, + *, + invalid_records: collections.abc.Iterable[osv.importfinding_pb2.ImportFinding] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["invalid_records", b"invalid_records"]) -> None: ... + +global___ImportFindingList = ImportFindingList + @typing.final class VersionMatch(google.protobuf.message.Message): """Match information for the provided VersionQuery.""" diff --git a/gcp/api/osv_service_v1_pb2_grpc.py b/gcp/api/osv_service_v1_pb2_grpc.py index 6df3c17b669..f4823f14ca4 100644 --- a/gcp/api/osv_service_v1_pb2_grpc.py +++ b/gcp/api/osv_service_v1_pb2_grpc.py @@ -61,6 +61,11 @@ def __init__(self, channel): request_serializer=osv__service__v1__pb2.DetermineVersionParameters.SerializeToString, response_deserializer=osv__service__v1__pb2.VersionMatchList.FromString, _registered_method=True) + self.ImportFindings = channel.unary_unary( + '/osv.v1.OSV/ImportFindings', + request_serializer=osv__service__v1__pb2.ImportFindingsParameters.SerializeToString, + response_deserializer=osv__service__v1__pb2.ImportFindingList.FromString, + _registered_method=True) class OSVServicer(object): @@ -98,6 +103,13 @@ def DetermineVersion(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def ImportFindings(self, request, context): + """Get import findings per source. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_OSVServicer_to_server(servicer, server): rpc_method_handlers = { @@ -121,6 +133,11 @@ def add_OSVServicer_to_server(servicer, server): request_deserializer=osv__service__v1__pb2.DetermineVersionParameters.FromString, response_serializer=osv__service__v1__pb2.VersionMatchList.SerializeToString, ), + 'ImportFindings': grpc.unary_unary_rpc_method_handler( + servicer.ImportFindings, + request_deserializer=osv__service__v1__pb2.ImportFindingsParameters.FromString, + response_serializer=osv__service__v1__pb2.ImportFindingList.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'osv.v1.OSV', rpc_method_handlers) @@ -240,3 +257,30 @@ def DetermineVersion(request, timeout, metadata, _registered_method=True) + + @staticmethod + def ImportFindings(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/osv.v1.OSV/ImportFindings', + osv__service__v1__pb2.ImportFindingsParameters.SerializeToString, + osv__service__v1__pb2.ImportFindingList.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/gcp/api/server.py b/gcp/api/server.py index 6ab56533127..512cdebc9e3 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -44,6 +44,7 @@ from osv import semver_index from osv import purl_helpers from osv import vulnerability_pb2 +from osv import importfinding_pb2 from osv.logs import setup_gcp_logging from gcp.api import osv_service_v1_pb2 from gcp.api import osv_service_v1_pb2_grpc @@ -345,6 +346,32 @@ def DetermineVersion(self, request, context: grpc.ServicerContext): res = determine_version(request.query, context).result() return res + @ndb_context + @trace_filter.log_trace + def ImportFindings(self, request, context: grpc.ServicerContext): + """Return a list of `ImportFinding` for a given source.""" + source = request.source + # TODO(gongh@): add source check + if not source: + context.abort(grpc.StatusCode.INVALID_ARGUMENT, 'Source is required.') + if get_gcp_project() == _TEST_INSTANCE: + logging.info('Checking import finding for %s\n', source) + + query = osv.ImportFinding.query(osv.ImportFinding.source == source) + import_findings: list[osv.ImportFinding] = query.fetch() + invalid_records = [] + for finding in import_findings: + invalid_records.append( + importfinding_pb2.ImportFinding( + bug_id=finding.bug_id, + source=finding.source, + findings=finding.findings, # type: ignore + first_seen=finding.first_seen.timestamp_pb(), #type: ignore + last_attempt=finding.last_attempt.timestamp_pb(), #type: ignore + )) + + return osv_service_v1_pb2.ImportFindingList(invalid_records=invalid_records) + @ndb_context def Check(self, request, context: grpc.ServicerContext): """Health check per the gRPC health check protocol.""" diff --git a/gcp/api/v1/api_descriptor.pb b/gcp/api/v1/api_descriptor.pb index 8a0c1e373a8f5466c98459e7b4d3cfe4197a1641..85d800a8793064fd038b97b1d0d80f400d00e638 100644 GIT binary patch delta 4762 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 (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _ImportFindingType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ImportFindingTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ImportFindingType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + IMPORT_FINDING_TYPE_NONE: _ImportFindingType.ValueType # 0 + IMPORT_FINDING_TYPE_DELETED: _ImportFindingType.ValueType # 1 + IMPORT_FINDING_TYPE_INVALID_JSON: _ImportFindingType.ValueType # 2 + IMPORT_FINDING_TYPE_INVALID_PACKAGE: _ImportFindingType.ValueType # 3 + IMPORT_FINDING_TYPE_INVALID_PURL: _ImportFindingType.ValueType # 4 + IMPORT_FINDING_TYPE_INVALID_VERSION: _ImportFindingType.ValueType # 5 + IMPORT_FINDING_TYPE_INVALID_COMMIT: _ImportFindingType.ValueType # 6 + IMPORT_FINDING_TYPE_INVALID_RANGE: _ImportFindingType.ValueType # 7 + IMPORT_FINDING_TYPE_BAD_ALIASED_CVE: _ImportFindingType.ValueType # 8 + +class ImportFindingType(_ImportFindingType, metaclass=_ImportFindingTypeEnumTypeWrapper): ... + +IMPORT_FINDING_TYPE_NONE: ImportFindingType.ValueType # 0 +IMPORT_FINDING_TYPE_DELETED: ImportFindingType.ValueType # 1 +IMPORT_FINDING_TYPE_INVALID_JSON: ImportFindingType.ValueType # 2 +IMPORT_FINDING_TYPE_INVALID_PACKAGE: ImportFindingType.ValueType # 3 +IMPORT_FINDING_TYPE_INVALID_PURL: ImportFindingType.ValueType # 4 +IMPORT_FINDING_TYPE_INVALID_VERSION: ImportFindingType.ValueType # 5 +IMPORT_FINDING_TYPE_INVALID_COMMIT: ImportFindingType.ValueType # 6 +IMPORT_FINDING_TYPE_INVALID_RANGE: ImportFindingType.ValueType # 7 +IMPORT_FINDING_TYPE_BAD_ALIASED_CVE: ImportFindingType.ValueType # 8 +global___ImportFindingType = ImportFindingType + +@typing.final +class ImportFinding(google.protobuf.message.Message): + """An importfinding entry. + The protobuf representation is *NOT* stable and only used for implementing + the JSON based API. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BUG_ID_FIELD_NUMBER: builtins.int + SOURCE_FIELD_NUMBER: builtins.int + FINDINGS_FIELD_NUMBER: builtins.int + FIRST_SEEN_FIELD_NUMBER: builtins.int + LAST_ATTEMPT_FIELD_NUMBER: builtins.int + bug_id: builtins.str + source: builtins.str + @property + def findings(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___ImportFindingType.ValueType]: ... + @property + def first_seen(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + @property + def last_attempt(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + def __init__( + self, + *, + bug_id: builtins.str = ..., + source: builtins.str = ..., + findings: collections.abc.Iterable[global___ImportFindingType.ValueType] | None = ..., + first_seen: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_attempt: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["first_seen", b"first_seen", "last_attempt", b"last_attempt"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["bug_id", b"bug_id", "findings", b"findings", "first_seen", b"first_seen", "last_attempt", b"last_attempt", "source", b"source"]) -> None: ... + +global___ImportFinding = ImportFinding diff --git a/osv/vulnerability_pb2.py b/osv/vulnerability_pb2.py index 9916ad35fe8..62ecf4bfa07 100644 --- a/osv/vulnerability_pb2.py +++ b/osv/vulnerability_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: osv/vulnerability.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -21,8 +21,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'osv.vulnerability_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None _globals['_COMMIT']._serialized_start=95 _globals['_COMMIT']._serialized_end=216 _globals['_COMMIT_REPOTYPE']._serialized_start=180 From ff279d1a450e0f839e310f46db3c7132e286ef4e Mon Sep 17 00:00:00 2001 From: Holly Gong Date: Thu, 19 Dec 2024 14:24:19 +1100 Subject: [PATCH 2/3] change to v1experimental/ endpoint --- gcp/api/osv_service_v1_pb2.py | 6 +++--- gcp/api/server.py | 16 +++++----------- gcp/api/v1/api_descriptor.pb | Bin 115682 -> 115694 bytes gcp/api/v1/osv_service_v1.proto | 2 +- osv/models.py | 11 +++++++++++ 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/gcp/api/osv_service_v1_pb2.py b/gcp/api/osv_service_v1_pb2.py index af8f1c26fa5..1c6806737b6 100644 --- a/gcp/api/osv_service_v1_pb2.py +++ b/gcp/api/osv_service_v1_pb2.py @@ -17,7 +17,7 @@ from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14osv_service_v1.proto\x12\x06osv.v1\x1a\x17osv/vulnerability.proto\x1a\x17osv/importfinding.proto\x1a\x1cgoogle/api/annotations.proto\"O\n\x11VulnerabilityList\x12!\n\x05vulns\x18\x01 \x03(\x0b\x32\x12.osv.Vulnerability\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\"D\n\x16\x42\x61tchVulnerabilityList\x12*\n\x07results\x18\x01 \x03(\x0b\x32\x19.osv.v1.VulnerabilityList\"h\n\x05Query\x12\x10\n\x06\x63ommit\x18\x01 \x01(\tH\x00\x12\x11\n\x07version\x18\x02 \x01(\tH\x00\x12\x1d\n\x07package\x18\x04 \x01(\x0b\x32\x0c.osv.Package\x12\x12\n\npage_token\x18\x05 \x01(\tB\x07\n\x05param\",\n\nBatchQuery\x12\x1e\n\x07queries\x18\x01 \x03(\x0b\x32\r.osv.v1.Query\"#\n\x15GetVulnByIdParameters\x12\n\n\x02id\x18\x01 \x01(\t\"7\n\x17QueryAffectedParameters\x12\x1c\n\x05query\x18\x01 \x01(\x0b\x32\r.osv.v1.Query\"A\n\x1cQueryAffectedBatchParameters\x12!\n\x05query\x18\x01 \x01(\x0b\x32\x12.osv.v1.BatchQuery\"A\n\x1a\x44\x65termineVersionParameters\x12#\n\x05query\x18\x01 \x01(\x0b\x32\x14.osv.v1.VersionQuery\"*\n\x18ImportFindingsParameters\x12\x0e\n\x06source\x18\x01 \x01(\t\"C\n\x0cVersionQuery\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x0b\x66ile_hashes\x18\x02 \x03(\x0b\x32\x10.osv.v1.FileHash\"n\n\x08\x46ileHash\x12\x11\n\tfile_path\x18\x01 \x01(\t\x12,\n\thash_type\x18\x02 \x01(\x0e\x32\x19.osv.v1.FileHash.HashType\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\"\x13\n\x08HashType\x12\x07\n\x03MD5\x10\x00\"9\n\x10VersionMatchList\x12%\n\x07matches\x18\x01 \x03(\x0b\x32\x14.osv.v1.VersionMatch\"@\n\x11ImportFindingList\x12+\n\x0finvalid_records\x18\x01 \x03(\x0b\x32\x12.osv.ImportFinding\"\xc7\x01\n\x0cVersionMatch\x12\r\n\x05score\x18\x01 \x01(\x01\x12\x37\n\trepo_info\x18\x02 \x01(\x0b\x32$.osv.v1.VersionRepositoryInformation\x12$\n\x0eosv_identifier\x18\x03 \x01(\x0b\x32\x0c.osv.Package\x12\r\n\x05\x63pe23\x18\x05 \x01(\t\x12\x1c\n\x14minimum_file_matches\x18\x06 \x01(\x03\x12\x1c\n\x14\x65stimated_diff_files\x18\x07 \x01(\x03\"\xc0\x01\n\x1cVersionRepositoryInformation\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.osv.v1.VersionRepositoryInformation.RepoType\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x0b\n\x03tag\x18\x04 \x01(\t\x12\x0f\n\x07version\x18\x05 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x06 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x32\xb9\x04\n\x03OSV\x12X\n\x0bGetVulnById\x12\x1d.osv.v1.GetVulnByIdParameters\x1a\x12.osv.Vulnerability\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/vulns/{id}\x12\x65\n\rQueryAffected\x12\x1f.osv.v1.QueryAffectedParameters\x1a\x19.osv.v1.VulnerabilityList\"\x18\x82\xd3\xe4\x93\x02\x12\"\t/v1/query:\x05query\x12y\n\x12QueryAffectedBatch\x12$.osv.v1.QueryAffectedBatchParameters\x1a\x1e.osv.v1.BatchVulnerabilityList\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x0e/v1/querybatch:\x05query\x12\x81\x01\n\x10\x44\x65termineVersion\x12\".osv.v1.DetermineVersionParameters\x1a\x18.osv.v1.VersionMatchList\"/\x82\xd3\xe4\x93\x02)\" /v1experimental/determineversion:\x05query\x12r\n\x0eImportFindings\x12 .osv.v1.ImportFindingsParameters\x1a\x19.osv.v1.ImportFindingList\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/v1/importfindings/{source}b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14osv_service_v1.proto\x12\x06osv.v1\x1a\x17osv/vulnerability.proto\x1a\x17osv/importfinding.proto\x1a\x1cgoogle/api/annotations.proto\"O\n\x11VulnerabilityList\x12!\n\x05vulns\x18\x01 \x03(\x0b\x32\x12.osv.Vulnerability\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\"D\n\x16\x42\x61tchVulnerabilityList\x12*\n\x07results\x18\x01 \x03(\x0b\x32\x19.osv.v1.VulnerabilityList\"h\n\x05Query\x12\x10\n\x06\x63ommit\x18\x01 \x01(\tH\x00\x12\x11\n\x07version\x18\x02 \x01(\tH\x00\x12\x1d\n\x07package\x18\x04 \x01(\x0b\x32\x0c.osv.Package\x12\x12\n\npage_token\x18\x05 \x01(\tB\x07\n\x05param\",\n\nBatchQuery\x12\x1e\n\x07queries\x18\x01 \x03(\x0b\x32\r.osv.v1.Query\"#\n\x15GetVulnByIdParameters\x12\n\n\x02id\x18\x01 \x01(\t\"7\n\x17QueryAffectedParameters\x12\x1c\n\x05query\x18\x01 \x01(\x0b\x32\r.osv.v1.Query\"A\n\x1cQueryAffectedBatchParameters\x12!\n\x05query\x18\x01 \x01(\x0b\x32\x12.osv.v1.BatchQuery\"A\n\x1a\x44\x65termineVersionParameters\x12#\n\x05query\x18\x01 \x01(\x0b\x32\x14.osv.v1.VersionQuery\"*\n\x18ImportFindingsParameters\x12\x0e\n\x06source\x18\x01 \x01(\t\"C\n\x0cVersionQuery\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x0b\x66ile_hashes\x18\x02 \x03(\x0b\x32\x10.osv.v1.FileHash\"n\n\x08\x46ileHash\x12\x11\n\tfile_path\x18\x01 \x01(\t\x12,\n\thash_type\x18\x02 \x01(\x0e\x32\x19.osv.v1.FileHash.HashType\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\"\x13\n\x08HashType\x12\x07\n\x03MD5\x10\x00\"9\n\x10VersionMatchList\x12%\n\x07matches\x18\x01 \x03(\x0b\x32\x14.osv.v1.VersionMatch\"@\n\x11ImportFindingList\x12+\n\x0finvalid_records\x18\x01 \x03(\x0b\x32\x12.osv.ImportFinding\"\xc7\x01\n\x0cVersionMatch\x12\r\n\x05score\x18\x01 \x01(\x01\x12\x37\n\trepo_info\x18\x02 \x01(\x0b\x32$.osv.v1.VersionRepositoryInformation\x12$\n\x0eosv_identifier\x18\x03 \x01(\x0b\x32\x0c.osv.Package\x12\r\n\x05\x63pe23\x18\x05 \x01(\t\x12\x1c\n\x14minimum_file_matches\x18\x06 \x01(\x03\x12\x1c\n\x14\x65stimated_diff_files\x18\x07 \x01(\x03\"\xc0\x01\n\x1cVersionRepositoryInformation\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.osv.v1.VersionRepositoryInformation.RepoType\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x0b\n\x03tag\x18\x04 \x01(\t\x12\x0f\n\x07version\x18\x05 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x06 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x32\xc5\x04\n\x03OSV\x12X\n\x0bGetVulnById\x12\x1d.osv.v1.GetVulnByIdParameters\x1a\x12.osv.Vulnerability\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/vulns/{id}\x12\x65\n\rQueryAffected\x12\x1f.osv.v1.QueryAffectedParameters\x1a\x19.osv.v1.VulnerabilityList\"\x18\x82\xd3\xe4\x93\x02\x12\"\t/v1/query:\x05query\x12y\n\x12QueryAffectedBatch\x12$.osv.v1.QueryAffectedBatchParameters\x1a\x1e.osv.v1.BatchVulnerabilityList\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x0e/v1/querybatch:\x05query\x12\x81\x01\n\x10\x44\x65termineVersion\x12\".osv.v1.DetermineVersionParameters\x1a\x18.osv.v1.VersionMatchList\"/\x82\xd3\xe4\x93\x02)\" /v1experimental/determineversion:\x05query\x12~\n\x0eImportFindings\x12 .osv.v1.ImportFindingsParameters\x1a\x19.osv.v1.ImportFindingList\"/\x82\xd3\xe4\x93\x02)\x12\'/v1experimental/importfindings/{source}b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,7 +33,7 @@ _globals['_OSV'].methods_by_name['DetermineVersion']._loaded_options = None _globals['_OSV'].methods_by_name['DetermineVersion']._serialized_options = b'\202\323\344\223\002)\" /v1experimental/determineversion:\005query' _globals['_OSV'].methods_by_name['ImportFindings']._loaded_options = None - _globals['_OSV'].methods_by_name['ImportFindings']._serialized_options = b'\202\323\344\223\002\035\022\033/v1/importfindings/{source}' + _globals['_OSV'].methods_by_name['ImportFindings']._serialized_options = b'\202\323\344\223\002)\022\'/v1experimental/importfindings/{source}' _globals['_VULNERABILITYLIST']._serialized_start=112 _globals['_VULNERABILITYLIST']._serialized_end=191 _globals['_BATCHVULNERABILITYLIST']._serialized_start=193 @@ -69,5 +69,5 @@ _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_start=1352 _globals['_VERSIONREPOSITORYINFORMATION_REPOTYPE']._serialized_end=1388 _globals['_OSV']._serialized_start=1391 - _globals['_OSV']._serialized_end=1960 + _globals['_OSV']._serialized_end=1972 # @@protoc_insertion_point(module_scope) diff --git a/gcp/api/server.py b/gcp/api/server.py index 512cdebc9e3..13e0cfb1e5f 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -44,7 +44,6 @@ from osv import semver_index from osv import purl_helpers from osv import vulnerability_pb2 -from osv import importfinding_pb2 from osv.logs import setup_gcp_logging from gcp.api import osv_service_v1_pb2 from gcp.api import osv_service_v1_pb2_grpc @@ -351,9 +350,11 @@ def DetermineVersion(self, request, context: grpc.ServicerContext): def ImportFindings(self, request, context: grpc.ServicerContext): """Return a list of `ImportFinding` for a given source.""" source = request.source - # TODO(gongh@): add source check + # TODO(gongh@): add source check, + # check if the source name exists in the source repository. if not source: - context.abort(grpc.StatusCode.INVALID_ARGUMENT, 'Source is required.') + context.abort(grpc.StatusCode.INVALID_ARGUMENT, + 'Missing Source: Please specify the source') if get_gcp_project() == _TEST_INSTANCE: logging.info('Checking import finding for %s\n', source) @@ -361,14 +362,7 @@ def ImportFindings(self, request, context: grpc.ServicerContext): import_findings: list[osv.ImportFinding] = query.fetch() invalid_records = [] for finding in import_findings: - invalid_records.append( - importfinding_pb2.ImportFinding( - bug_id=finding.bug_id, - source=finding.source, - findings=finding.findings, # type: ignore - first_seen=finding.first_seen.timestamp_pb(), #type: ignore - last_attempt=finding.last_attempt.timestamp_pb(), #type: ignore - )) + invalid_records.append(finding.to_proto()) return osv_service_v1_pb2.ImportFindingList(invalid_records=invalid_records) diff --git a/gcp/api/v1/api_descriptor.pb b/gcp/api/v1/api_descriptor.pb index 85d800a8793064fd038b97b1d0d80f400d00e638..993a5c17e94d2c11e7c03706f992b533c6e73bc8 100644 GIT binary patch delta 65 zcmV-H0KWg?hX?M52Y|EzV5R|#w_&CMmj(gFxB09A#{mI;m%*+9P8ctO)8vx^DH10y Xb}?mmaAk67ZDnqBVQjY>uK~vtjm8>? delta 53 zcmV-50LuUFhX>+^2Y|EzV5R|pw_&CMmj(g3xB09A#{mIym%*+9P7EW0)8vx^9TFQa Lb}_dnuK~vtVfGa= diff --git a/gcp/api/v1/osv_service_v1.proto b/gcp/api/v1/osv_service_v1.proto index 98f01cc54b4..5da0e1afa41 100644 --- a/gcp/api/v1/osv_service_v1.proto +++ b/gcp/api/v1/osv_service_v1.proto @@ -181,7 +181,7 @@ service OSV { // Get import findings per source. rpc ImportFindings(ImportFindingsParameters) returns (ImportFindingList) { option (google.api.http) = { - get: "/v1/importfindings/{source}" + get: "/v1experimental/importfindings/{source}" }; } } diff --git a/osv/models.py b/osv/models.py index 8dd7eabe81a..631b5dd64bb 100644 --- a/osv/models.py +++ b/osv/models.py @@ -25,6 +25,7 @@ from google.cloud import ndb from google.protobuf import json_format from google.protobuf import timestamp_pb2 +from osv import importfinding_pb2 # pylint: disable=relative-beyond-top-level from . import bug @@ -930,6 +931,16 @@ def _pre_put_hook(self): # pylint: disable=arguments-differ if not self.key: # pylint: disable=access-member-before-definition self.key = ndb.Key(ImportFinding, self.bug_id) + def to_proto(self): + """Converts to ImportFinding proto.""" + return importfinding_pb2.ImportFinding( + bug_id=self.bug_id, + source=self.source, + findings=self.findings, # type: ignore + first_seen=self.first_seen.timestamp_pb(), #type: ignore + last_attempt=self.last_attempt.timestamp_pb(), #type: ignore + ) + def get_source_repository(source_name: str) -> SourceRepository: """Get source repository.""" From 26c0e0a21de2a2c3fc6dcb207347339e6ec3f18a Mon Sep 17 00:00:00 2001 From: Andrew Pollock Date: Tue, 24 Dec 2024 07:49:41 +0000 Subject: [PATCH 3/3] docs: add documentation for importfinding API --- docs/api/get-v1-importfindings.md | 59 +++++++++++++++++++++++++++++++ docs/api/index.md | 10 ++++-- 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 docs/api/get-v1-importfindings.md diff --git a/docs/api/get-v1-importfindings.md b/docs/api/get-v1-importfindings.md new file mode 100644 index 00000000000..b925e79ed1f --- /dev/null +++ b/docs/api/get-v1-importfindings.md @@ -0,0 +1,59 @@ +--- +layout: page +title: GET /v1experimental/importfindings +permalink: /get-v1-importfindings/ +parent: API +nav_order: 5 +--- +# GET /v1experimental/importfindings/{source} +Experimental +{: .label } + +Given a specific OSV.dev source, report any records that are failing import-time quality checks. + +{: .no_toc } + +
+ + Table of contents + + {: .text-delta } +- TOC +{:toc} +
+ +## Experimental endpoint + +This API endpoint is still considered experimental. It is targeted to operators +of home databases that OSV.dev imports from. We would value any and all +feedback. If you give this a try, please consider [opening an +issue](https://github.com/google/osv.dev/issues/new) and letting us know about +any pain points or highlights. + +## Purpose + +The purpose of this endpoint is give OSV record providers (home database +operators) a machine-readable way to reason about records they have published that +do not meet [OSV.dev's quality bar](data_quality.html) (and therefore have not been imported). + +## Parameters + +The only parameter you need for this API call is the source, in order to construct the URL. + +`https://api.osv.dev/v1/importfindings/{source}` + +The `source` value is the same as the `name` value in [`source.yaml`](https://github.com/google/osv.dev/blob/master/source.yaml) + +Case Sensitivity: API requests are case-sensitive. Please ensure that you use the correct case for parameter names and values. For example, use 'ghsa' instead of 'GHSA'. + +## Request sample + +```bash +curl "https://api.osv.dev/v1experimental/importfindings/example" +``` + +## Example 200 response + +``` +{"invalid_records":[{"bug_id":"EX-1234","source":"example","findings":["IMPORT_FINDING_TYPE_INVALID_JSON"],"first_seen":"2024-12-19T15:18:00.945105Z","last_attempt":"2024-12-19T15:18:00.945105Z"}]} +``` diff --git a/docs/api/index.md b/docs/api/index.md index e19f2f52407..8b5970f1553 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -8,21 +8,25 @@ nav_order: 2 # API (1.0) ## Download the OpenAPI specification + [Download Here](https://osv.dev/docs/osv_service_v1.swagger.json){: .btn .btn-purple} ## OSV API ### Want a quick example? -Please see the [quickstart](api-quickstart.md). + +Please see the [quickstart](api-quickstart.md). ### How does the API work? -There are four different types of requests that can be made of the API. +There are five different types of requests that can be made of the API. 1. Query vulnerabilities for a particular project at a given [commit hash or version](post-v1-query.md). 2. [Batched query vulnerabilities](post-v1-querybatch.md) for given package versions and commit hashes. 3. Return a `Vulnerability` object for a given [OSV ID](get-v1-vulns.md). 4. Return a list of [probable versions](post-v1-determineversion.md) of a specified C/C++ project. (**Experimental**) +5. Retrieve [records failing import-time quality checks](get-v1-importfindings.md), by record source (**Experimental**) ### Is the API rate limited? -Currently there are no limits on the API. \ No newline at end of file + +Currently there are no limits on the API.