Commit 0ccc0a1e authored by PidgeyL's avatar PidgeyL
Browse files

Add query and link to api

parent c4772a1b
Loading
Loading
Loading
Loading
+78 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import json
import logging
import os
import random
import re
import signal
import sys
import time
@@ -59,11 +60,13 @@ class API():
              {'r': '/api/last',                           'm': ['GET'], 'f': self.api_last},
              {'r': '/api/last/',                          'm': ['GET'], 'f': self.api_last},
              {'r': '/api/last/<int:limit>',               'm': ['GET'], 'f': self.api_last},
              {'r': '/api/query',                          'm': ['GET'], 'f': self.api_query},
              {'r': '/api/browse',                         'm': ['GET'], 'f': self.api_browse},
              {'r': '/api/browse/',                        'm': ['GET'], 'f': self.api_browse},
              {'r': '/api/browse/<path:vendor>',           'm': ['GET'], 'f': self.api_browse},
              {'r': '/api/search/<vendor>/<path:product>', 'm': ['GET'], 'f': self.api_search},
              {'r': '/api/search/<path:search>',           'm': ['GET'], 'f': self.api_text_search},
              {'r': '/api/link/<key>/<value>',             'm': ['GET'], 'f': self.api_link},
              {'r': '/api/dbInfo',                         'm': ['GET'], 'f': self.api_dbInfo}]
    for route in routes: self.addRoute(route)

@@ -87,7 +90,8 @@ class API():
        error = {'status': 'error', 'reason': 'Internal server error'}
      # Check if data should be returned as html or data
      try:
        if request.url_rule.rule.lower().startswith("/api/"):
        if (request.url_rule.rule.lower().startswith("/api/") or
           request.url_rule.rule.lower().endswith(".json") ):
          # Support JSONP
          if request.args.get('callback', False):
            data="%s(%s)"%(request.args.get('callback'), data)
@@ -113,6 +117,43 @@ class API():
      return data
    return api_wrapper

  #############
  # FUNCTIONS #
  #############
  def generate_minimal_query(self, f):
    query = []
    # retrieving lists
    if f['rejectedSelect'] == "hide":
      exp = "^(?!\*\* REJECT \*\*\s+DO NOT USE THIS CANDIDATE NUMBER.*)"
      query.append({'summary': re.compile(exp)})

    # cvss logic
    if   f['cvssSelect'] == "above":  query.append({'cvss': {'$gt': float(f['cvss'])}})
    elif f['cvssSelect'] == "equals": query.append({'cvss': float(f['cvss'])})
    elif f['cvssSelect'] == "below":  query.append({'cvss': {'$lt': float(f['cvss'])}})

    # date logic
    if f['timeSelect'] != "all":
      if f['startDate']:
        startDate = parse_datetime(f['startDate'], ignoretz=True, dayfirst=True)
      if f['endDate']:
        endDate   = parse_datetime(f['endDate'],   ignoretz=True, dayfirst=True)

      if   f['timeSelect'] == "from":
        query.append({f['timeTypeSelect']: {'$gt': startDate}})
      elif f['timeSelect'] == "until":
        query.append({f['timeTypeSelect']: {'$lt': endDate}})
      elif f['timeSelect'] == "between":
        query.append({f['timeTypeSelect']: {'$gt': startDate, '$lt': endDate}})
      elif f['timeSelect'] == "outside":
        query.append({'$or': [{f['timeTypeSelect']: {'$lt': startDate}}, {f['timeTypeSelect']: {'$gt': endDate}}]})
    return query

  def filter_logic(self, filters, skip, limit=None):
    query = self.generate_minimal_query(filters)
    limit = limit if limit else self.args['pageLength']
    return db.getCVEs(limit=limit, skip=skip, query=query)

  ##########
  # ROUTES #
  ##########
@@ -167,6 +208,28 @@ class API():
    cve = cvesp.get(limit=limit)
    return cve

  # /query
  @api
  def api_query(self):
    f={'rejectedSelect': request.headers.get('rejected'),
       'cvss':           request.headers.get('cvss_score'),
       'cvssSelect':     request.headers.get('cvss_modifier'),
       'startDate':      request.headers.get('time_start'),
       'endDate':        request.headers.get('time_end'),
       'timeSelect':     request.headers.get('time_modifier'),
       'timeTypeSelect': request.headers.get('time_type'),
       'skip':           request.headers.get('skip'),
       'limit':          request.headers.get('limit')}
    try:
      skip = int(f['skip']) if f['skip'] else 0
    except:
      raise(APIError('skip must be an int'))
    try:
      limit = int(f['limit']) if f['limit'] else 0
    except:
      raise(APIError('limit must be an int'))  
    return self.filter_logic(f, skip, limit)

  # /api/browse
  # /api/browse/
  # /api/browse/<vendor>
@@ -197,6 +260,20 @@ class API():
  def api_text_search(self, search=None):
    return db.getSearchResults(search)

  # /api/link/<key>/<value>
  @api
  def api_link(self, key=None,value=None):
    key=self.htmlDecode(key)
    value=self.htmlDecode(value)
    regex = re.compile(re.escape(value), re.I)
    data = {'cves': db.via4Linked(key, regex)}
    cvssList=[float(x['cvss']) for x in data['cves'] if 'cvss' in x]
    if cvssList:
        data['stats']={'maxCVSS': max(cvssList), 'minCVSS': min(cvssList),'count':len(data['cves'])}
    else:
        data['stats']={'maxCVSS': 0, 'minCVSS': 0, 'count':len(data['cves'])}
    return data

  # /api/dbInfo
  @api
  def api_dbInfo(self):
+0 −35
Original line number Diff line number Diff line
@@ -78,41 +78,6 @@ class Minimal(API):
  def addContextProcessors(self, context_processor):
    self.app.context_processor(context_processor)

  def generate_minimal_query(self, f):
    query = []
    # retrieving lists
    if f['rejectedSelect'] == "hide":
      exp = "^(?!\*\* REJECT \*\*\s+DO NOT USE THIS CANDIDATE NUMBER.*)"
      query.append({'summary': re.compile(exp)})

    # cvss logic
    if   f['cvssSelect'] == "above":  query.append({'cvss': {'$gt': float(f['cvss'])}})
    elif f['cvssSelect'] == "equals": query.append({'cvss': float(f['cvss'])})
    elif f['cvssSelect'] == "below":  query.append({'cvss': {'$lt': float(f['cvss'])}})

    # date logic
    if f['timeSelect'] != "all":
      if f['startDate']:
        startDate = parse_datetime(f['startDate'], ignoretz=True, dayfirst=True)
      if f['endDate']:
        endDate   = parse_datetime(f['endDate'],   ignoretz=True, dayfirst=True)

      if   f['timeSelect'] == "from":
        query.append({f['timeTypeSelect']: {'$gt': startDate}})
      elif f['timeSelect'] == "until":
        query.append({f['timeTypeSelect']: {'$lt': endDate}})
      elif f['timeSelect'] == "between":
        query.append({f['timeTypeSelect']: {'$gt': startDate, '$lt': endDate}})
      elif f['timeSelect'] == "outside":
        query.append({'$or': [{f['timeTypeSelect']: {'$lt': startDate}}, {f['timeTypeSelect']: {'$gt': endDate}}]})
    return query


  def filter_logic(self, filters, skip):
    query = self.generate_minimal_query(filters)
    limit = self.args['pageLength']
    return db.getCVEs(limit=limit, skip=skip, query=query)

  def getFilterSettingsFromPost(self, r):
    filters = dict(request.form)
    filters = {x: filters[x][0] for x in filters.keys()}