Skip to content

Commit

Permalink
Merge pull request #24 from gardenlinux/redefine-api
Browse files Browse the repository at this point in the history
Specify the API in more modern ways
  • Loading branch information
waldiTM authored Dec 12, 2023
2 parents 507cfd3 + 92ebca5 commit b1f5fde
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 119 deletions.
67 changes: 67 additions & 0 deletions openapi-v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
openapi: 3.0.3
info:
title: Garden Linux Vulnerability Database
contact:
email: [email protected]
license:
name: MIT
version: 0.1.0
servers:
- url: http://localhost:5000/v1
tags:
- name: cve
description: Everything about CVE
paths:
/cves/findByCpe:
get:
tags:
- cve
summary: Finds CVE by CPE
parameters:
- name: cpeName
in: query
description: CPE name to search for, only Debian/Garden Linux related CPE can be used
required: true
schema:
type: string
- name: cvssV3Severity
in: query
description: Not implemented
schema:
type: string
enum:
- LOW
- MEDIUM
- HIGH
- CRITICAL
- name: debVersionEnd
in: query
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema: {}
'400':
description: parameter is invalid
/cves/{cveId}:
get:
tags:
- cve
summary: Find CVE by ID
parameters:
- name: cveId
in: path
description: ID of CVE
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json: {}
'404':
description: CVE not found
4 changes: 2 additions & 2 deletions src/glvd/web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def create_app():

QuartDb(app)

from .nvd import bp as bp_nvd
app.register_blueprint(bp_nvd)
from .v1_cves import bp as bp_v1_cves
app.register_blueprint(bp_v1_cves)

return app
116 changes: 55 additions & 61 deletions src/glvd/web/nvd.py → src/glvd/web/v1_cves.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@

from ..data.cpe import Cpe

bp = Blueprint('nvd', __name__)
bp = Blueprint('nvd', __name__, url_prefix='/v1/cves')


stmt_cve_deb_cpe_version = (
stmt_cve_id = (
text('''
SELECT
all_cve.data AS cve
FROM
all_cve
WHERE
cve_id = :cve_id
GROUP BY
all_cve.cve_id
''')
.bindparams(
bindparam('cve_id'),
)
)

stmt_cpe_version = (
text('''
WITH data AS (
SELECT
Expand All @@ -33,12 +49,7 @@
all_cve.cve_id
)
SELECT
json_build_object(
'format', 'NVD_CVE',
'version', '2.0+deb',
'vulnerabilities', coalesce(json_agg(data), '[]'::json)
)::text
FROM data
coalesce(json_agg(data.cve), '[]'::json)::text FROM data
''')
.bindparams(
bindparam('cpe_vendor'),
Expand All @@ -49,7 +60,7 @@
)
)

stmt_cve_deb_cpe_vulnerable = (
stmt_cpe_vulnerable = (
text('''
WITH data AS (
SELECT
Expand All @@ -68,12 +79,7 @@
all_cve.cve_id
)
SELECT
json_build_object(
'format', 'NVD_CVE',
'version', '2.0+deb',
'vulnerabilities', coalesce(json_agg(data), '[]'::json)
)::text
FROM data
coalesce(json_agg(data.cve), '[]'::json)::text FROM data
''')
.bindparams(
bindparam('cpe_vendor'),
Expand All @@ -83,55 +89,43 @@
)
)

stmt_cve_deb_cve_id = (
text('''
WITH data AS (
SELECT
all_cve.data AS cve
FROM
all_cve
WHERE
cve_id = :cve_id
GROUP BY
all_cve.cve_id
)
SELECT
json_build_object(
'format', 'NVD_CVE',
'version', '2.0+deb',
'vulnerabilities', coalesce(json_agg(data), '[]'::json)
)::text
FROM data
''')
.bindparams(
bindparam('cve_id'),
)
)

@bp.route('/<cve_id>')
async def get_cve_id(cve_id):
stmt = stmt_cve_id.bindparams(cve_id=cve_id)

@bp.route('/rest/json/cves/2.0+deb')
async def nvd_cve_deb():
if cpe_name := request.args.get('virtualMatchString', type=str):
cpe = Cpe.parse(cpe_name)
if not cpe.is_debian:
return 'Not Debian related CPE', 400
if cpe.other.deb_source and (deb_version := request.args.get('debVersionEnd', type=str)):
stmt = stmt_cve_deb_cpe_version.bindparams(
cpe_vendor=cpe.vendor,
cpe_product=cpe.product,
cpe_version=cpe.version or '%',
deb_source=cpe.other.deb_source,
deb_version=deb_version,
)
async with current_app.db_begin() as conn:
data = (await conn.execute(stmt)).one_or_none()

if data:
return data[0], 200
else:
stmt = stmt_cve_deb_cpe_vulnerable.bindparams(
cpe_vendor=cpe.vendor,
cpe_product=cpe.product,
cpe_version=cpe.version or '%',
deb_source=cpe.other.deb_source or '%',
)
elif cve_id := request.args.get('cveId', type=str):
stmt = stmt_cve_deb_cve_id.bindparams(cve_id=cve_id)
return 'Not found', 404


@bp.route('/findByCpe')
async def get_cpe_name():
cpe = Cpe.parse(request.args.get('cpeName', type=str))
deb_version = request.args.get('debVersionEnd', type=str)

if not cpe.is_debian:
return 'Not Debian related CPE', 400

if cpe.other.deb_source and deb_version:
stmt = stmt_cpe_version.bindparams(
cpe_vendor=cpe.vendor,
cpe_product=cpe.product,
cpe_version=cpe.version or '%',
deb_source=cpe.other.deb_source,
deb_version=deb_version,
)
else:
stmt = stmt_cpe_vulnerable.bindparams(
cpe_vendor=cpe.vendor,
cpe_product=cpe.product,
cpe_version=cpe.version or '%',
deb_source=cpe.other.deb_source or '%',
)

async with current_app.db_begin() as conn:
return (
Expand Down
56 changes: 0 additions & 56 deletions tests/web/test_nvd_cve.py

This file was deleted.

Loading

0 comments on commit b1f5fde

Please sign in to comment.