def merge_results(results, scan_id=None): for result in results: logger.info('{} merge results'.format(result)) # with db.session_scope() as session: # scan = get_scan(scan_id, session) # After the merge we remove the folder with the scan source scan_dir = os.path.join(SHARED_VOLUME_PATH, scan_id) try: shutil.rmtree(scan_dir) except IOError as e: logger.error("Error while removing tmp dir: {} - {}".format( scan_dir, e)) with db.session_scope() as session: scan = get_scan(scan_id, session) project = scan.project scan = update_scan_state(scan, ScanState.DONE, session) session.commit() if project.hook_type != ProjectHookType.NONE.name: # launch notify task logger.debug('{} launch notify task for project.hook_type'.format( scan.id)) notify_results.delay(scan.id)
def add_scan_for_project_with_repo(repo_url: str, branch: str=None): """ If a project with repo_url exists in the database, adds a scan to it :param repo_url: (str) repo url for the project to launch the scan :param branch: (str, Optional) branch for the project to launch the scan :return: """ assert type(repo_url) is str with db.session_scope() as session: project = get_project_by_repo(repo_url, session) allowed_scan = True if ALLOWED_SCANS_PER_PERIOD > 0: previous_scans = get_num_scans_in_last_minutes(project.id, ALLOWED_SCANS_CHECK_PERIOD, session) allowed_scan = previous_scans < ALLOWED_SCANS_PER_PERIOD if allowed_scan: scan = add_scan(project.id, session, branch=branch) session.commit() celery = Celery('deeptracy', broker=BROKER_URI) celery.send_task('prepare_scan', [scan.id]) else: raise APIError('cant create more scans', status_code=503)
def notify_patton_deltas(vulnerabilities): scan_dep_by_project_id = {} with db.session_scope() as session: for cpe in vulnerabilities: scan_deps_ids = [] cves = vulnerabilities[cpe] for vuln_db in get_vulns_for_cpe(cpe, session): for scan_vuln in vuln_db.scan_vulns: scan_dep = scan_vuln.scan_dep scan_deps_ids.append(scan_dep.id) raw_dep = scan_dep.raw_dep scan = scan_dep.scan project = scan.project if project.id in scan_dep_by_project_id: scan_dep_by_project_id[project.id]['dependencies'].append(raw_dep) else: scan_dep_by_project_id[project.id] = {'project': project, 'dependencies': [raw_dep]} for scan_dep_id in set(scan_deps_ids): add_vulns_in_scan_dep(cpe=cpe, cves=cves, scan_dep_id=scan_dep_id, session=session) for project_id in scan_dep_by_project_id: elem = scan_dep_by_project_id[project_id] dependencies = set(elem['dependencies']) notify_deltas(elem['project'], dependencies) logger.debug('notify vulnerabilities')
def get_projects(): """List Projects Retrieves a list of all projects on database. Example: :return codes: 200 on success 404 on errors """ filter = request.args.get('filter') with db.session_scope() as session: try: if filter: if filter == 'count': return jsonify(project_manager.get_projects_count(session)), 200 else: return api_error_response('Filter not exists'), 400 else: term = request.args.get('term') if term: projects = project_manager.get_projects_by_name_term(term, 20, session) else: projects = project_manager.get_projects(session) project_arr = [project.to_dict() for project in projects] return jsonify(project_arr), 200 except Exception as exc: return api_error_response(exc.args[0]), 400
def post_delta(): """Add new vulnerabilities on the database Add new vulnerabilities on existing project Example: Body { "project_id": "00001", "lang": "javascript", "branch": "develop" //Optional } :return codes: 201 on success 400 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 celery = Celery('deeptracy', broker=BROKER_URI) celery.send_task('notify_patton_deltas', [data]) return "Se ha procesado correctamente", 201
def update_project(project_id): """Updates a project on the database Update repo url on existing project Example: Body {"repo": "http://google.com"} :return codes: 201 on success 400 on errors """ data = request.get_json() if not data: return api_error_response('invalid payload'), 400 repo = data.get('repo', None) if repo is not None or repo == '': return api_error_response('can not update repo'), 400 with db.session_scope() as session: try: project = project_manager.update_project(project_id, session, **data) session.commit() except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 400 return jsonify(project.to_dict()), 201
def update_project(project_id): """Updates a project on the database Update repo url on existing project Example: Body {"repo": "http://google.com"} :return codes: 201 on success 400 on errors """ data = request.get_json() if not data: return api_error_response('invalid payload'), 400 repo = data.get('repo', None) if repo is not None or repo == '': return api_error_response('can not update repo'), 400 with db.session_scope() as session: try: project = project_manager.update_project(project_id, session, **data) session.commit() except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 400 return jsonify(project.to_dict()), 201
def get_projects(): """List Projects Retrieves a list of all projects on database. Example: :return codes: 200 on success 404 on errors """ filter = request.args.get('filter') with db.session_scope() as session: try: if filter: if filter == 'count': return jsonify( project_manager.get_projects_count(session)), 200 else: return api_error_response('Filter not exists'), 400 else: term = request.args.get('term') if term: projects = project_manager.get_projects_by_name_term( term, 20, session) else: projects = project_manager.get_projects(session) project_arr = [project.to_dict() for project in projects] return jsonify(project_arr), 200 except Exception as exc: return api_error_response(exc.args[0]), 400
def get_vulnerabilities(scan_id): """Get scan vulnerabilities""" with db.session_scope() as session: try: scan_vulnerabilities = [ scan_vulnerability.to_dict() for scan_vulnerability in get_scan_vulnerabilities( scan_id, session) ] response = [] def fillResponse(scan_vulnerability): vulns = get_vulns_for_cpe(scan_vulnerability['cpe'], session) scan_dep = get_scan_dep_by_id( scan_vulnerability['scan_dep_id'], session) return [ response.append({ 'library': scan_dep.library, 'version': scan_dep.version, 'cpe': vuln.cpe, 'cve': vuln.cve }) for vuln in vulns ] [ fillResponse(scan_vulnerability) for scan_vulnerability in scan_vulnerabilities ] except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(response)
def scan_deps(scan_id: str): with db.session_scope() as session: logger.debug('{} extract dependencies'.format(scan_id)) scan = get_scan(scan_id, session) dependencies = get_dependencies(scan.lang, scan.source_path) logger.debug('found dependencies {}'.format(dependencies)) # save all dependencies in the database add_scan_deps(scan.id, dependencies, datetime.now(), session) scan.total_packages = len(dependencies) session.commit() logger.debug('saved {} dependencies'.format(len(dependencies))) # compare the dependencies in this scan with the last scan for this project previous_scan = get_previous_scan_for_project(scan.project_id, scan.id, session) if previous_scan is None: logger.debug('no previous scan found for {}'.format(scan_id)) deps_equals = False else: logger.debug('previous scan to {} is {}'.format( scan_id, previous_scan.id)) deps_equals = compare_scan_deps(scan.id, previous_scan.id, session) if deps_equals: update_scan_state(scan, ScanState.SAME_DEPS_AS_PREVIOUS, session) logger.debug('{} scan has same deps as {}'.format( scan_id, previous_scan.id)) if not deps_equals: get_vulnerabilities.delay(scan_id)
def post_delta(): """Add new vulnerabilities on the database Add new vulnerabilities on existing project Example: Body { "project_id": "00001", "lang": "javascript", "branch": "develop" //Optional } :return codes: 201 on success 400 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 celery = Celery('deeptracy', broker=BROKER_URI) celery.send_task('notify_patton_deltas', [data]) return "Se ha procesado correctamente", 201
def get_vulnerabilities(scan_id): """Get scan vulnerabilities""" with db.session_scope() as session: try: scan_vulnerabilities = [scan_vulnerability.to_dict() for scan_vulnerability in get_scan_vulnerabilities(scan_id, session)] except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(scan_vulnerabilities)
def post_project(): """Adds a project to the database It receive a Project in the body as a json object and tries to create the project in the database Example: Body {"repo": "http://google.com"} :return codes: 201 on success 400 on errors 409 on a duplicate repo """ data = request.get_json() if not data: return api_error_response('invalid payload'), 400 repo = data.get('repo', None) if repo is None or repo == '': return api_error_response('missing repo'), 400 else: data.pop('repo') # repo should not be present in data name = data.get('name', None) if name is None or name == '': name = repo.split('/')[-1] if data.get('name'): data.pop('name') # name should not be present in data email = data.get('email', None) if email is not None: hook_type = ProjectHookType.EMAIL.name hook_data = {"email": email} else: hook_type = ProjectHookType.NONE.name hook_data = {} with db.session_scope() as session: try: project = project_manager.add_project(repo, name, session, hook_type=hook_type, hook_data=hook_data, **data) session.commit() except Exception as exc: session.rollback() if 'unique constraint "project_repo_key"' in exc.args[0]: return api_error_response( 'unique constraint project repo {}'.format(repo)), 409 else: return api_error_response(exc.args[0]), 400 return jsonify(project.to_dict()), 201
def get_vulnerabilities(scan_id: str): with db.session_scope() as session: logger.debug('{} extract dependencies'.format(scan_id)) scan_deps = get_scan_deps(scan_id, session) scan = get_scan(scan_id, session) project = scan.project url = '{}/api/v1/check-dependencies?cpeDetailed=1'.format(PATTON_URI) req_body = { 'method': 'auto', 'source': 'auto', 'libraries': [{ 'library': scan_dep.library, 'version': scan_dep.version } for scan_dep in scan_deps] } response = requests.post(url, json=req_body).json() total_vulnerabilities = 0 if response: for key in response: if response[key]: [library, version] = key.split(':') scan_dep = get_scan_dep_by_scan_id_and_raw_dep( scan_id, '{}:{}'.format(library, version), session) cpes = response[key] for cpe_dict in cpes['cpes']: cpe = cpe_dict['cpe'] cves = cpe_dict['cves'] total_vulnerabilities += len(cves) # save all dependencies in the database add_scan_vuln(scan_dep.id, scan.id, scan.lang, cpe, cves, session) logger.info('saved {cves} cves for cpe {cpe}'.format( cves=len(cves), cpe=cpe)) scan.total_vulnerabilities = total_vulnerabilities update_scan_state(scan, ScanState.DONE, session) session.commit() # After the merge we remove the folder with the scan source scan_dir = os.path.join(SHARED_VOLUME_PATH, scan_id) try: shutil.rmtree(scan_dir) except IOError as e: logger.error("Error while removing tmp dir: {} - {}".format( scan_dir, e)) if project.hook_type != ProjectHookType.NONE.name: # launch notify task logger.debug('{} launch notify task for project.hook_type'.format( scan.id)) notify_results.delay(scan.id)
def notify_results(scan_id): with db.session_scope() as session: scan = get_scan(scan_id, session) scan_vulns = set([ scan_vuln.scan_dep.raw_dep for scan_vuln in get_scan_vulnerabilities(scan_id, session) ]) project = scan.project logger.debug('notify project data {}'.format(project.hook_data)) notify_scan_results(project, scan_vulns)
def notify_results(scan_id): with db.session_scope() as session: scan = get_scan(scan_id, session) scan_vulns = [ '{}:{}'.format(scan_vuln.library, scan_vuln.version) for scan_vuln in get_scan_vulnerabilities(scan_id, session) ] project = scan.project logger.debug('notify project data {}'.format(project.hook_data)) notify_scan_results(project, scan_vulns)
def notify_results(scan_id): with db.session_scope() as session: scan = get_scan(scan_id, session) project = scan.project logger.debug('notify project data {}'.format(project.hook_data)) notif_text = 'project at {} has vulnerabilities'.format(project.repo) if project.hook_type == ProjectHookType.SLACK.name: hook_data_dict = json.loads(project.hook_data) slack.notify(hook_data_dict.get('webhook_url'), notif_text)
def post_scan(): """Add a scan on the database Add a scan language on existing project Example: Body { "project_id": "00001", "lang": "javascript", "branch": "develop" //Optional } :return codes: 201 on success 400 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 project_id = get_required_field(data, 'project_id') lang = data.get('lang', None) branch = data.get('branch', None) if branch is None or branch == '': branch = 'master' else: project = get_project(project_id, session) command = 'git ls-remote --ref {}'.format(project.repo) # if defined, limit the number of scans that can be created by a given period for the same project logger.debug(' allowed scans per period {}/{}'.format( ALLOWED_SCANS_PER_PERIOD, ALLOWED_SCANS_CHECK_PERIOD)) allowed_scan = True if ALLOWED_SCANS_PER_PERIOD > 0: previous_scans = get_num_scans_in_last_minutes( project_id, ALLOWED_SCANS_CHECK_PERIOD, session) allowed_scan = previous_scans < ALLOWED_SCANS_PER_PERIOD if allowed_scan: scan = add_scan(project_id, session, lang=lang, branch=branch) session.commit() # when the scan is added to the database, a celery task is inserted for that scan to start the process celery = Celery('deeptracy', broker=BROKER_URI) celery.send_task('prepare_scan', [scan.id]) return jsonify(scan.to_dict()), 201 else: return api_error_response('cant create more scans'), 403
def prepare_scan(scan_id: str): with db.session_scope() as session: logger.info('{} START SCAN'.format(scan_id)) scan = get_scan(scan_id, session) project = scan.project logger.debug('{} for project({})'.format(scan_id, project.id)) try: # clone the repository in a shared volume cloned_dir = clone_project(config.SHARED_VOLUME_PATH, scan_id, project.repo, project.repo_auth_type, scan.branch) scan.source_path = cloned_dir session.add(scan) logger.debug('{} cloned dir {}'.format(scan_id, cloned_dir)) except Exception as e: update_scan_state(scan, ScanState.INVALID_BRANCH, session) session.commit() logger.error(str(e)) raise e # if a .deeptracy.yml is found, parse it to a dictionary try: deeptracy_yml = parse_deeptracy_yml(cloned_dir) logger.debug('{} .deeptracy.yml {}'.format( scan_id, 'TRUE' if deeptracy_yml else 'FALSE')) except Exception as e: update_scan_state(scan, ScanState.INVALID_YML_ON_PROJECT, session) session.commit() logger.error('{} unable to parse .deeptracy.yml'.format(scan_id)) raise e # the language for a scan can be specified on the scan of in the deeptracy file in the sources if scan.lang is None: if deeptracy_yml is None: update_scan_state(scan, ScanState.CANT_GET_LANGUAGE, session) session.commit() logger.debug( '{} unable to retrieve language for scan'.format(scan_id)) raise TaskException('unable to retrieve language for scan') else: lang = deeptracy_yml.get( 'lang') # the parse ensures us a valid lang in the dict scan.lang = lang # update the san object to store the language session.add(scan) # once the scan is ready continue with the dependency extraction scan_deps.delay(scan_id)
def get_vulnerabilities(scan_id: str): with db.session_scope() as session: logger.debug('{} extract dependencies'.format(scan_id)) scan_deps = get_scan_deps(scan_id, session) scan_deps_len = len(scan_deps) scan = get_scan(scan_id, session) project = scan.project total_vulnerabilities = [] def get_response(i, scan_dep): [package, version] = scan_dep.raw_dep.split(':') url = '{}/batch'.format(PATTON_URI) response = requests.post(url, json=[[package, version]]).json() print(response) logger.info("Procesado {} de {}".format(i, scan_deps_len)) if response: for key in response: if response[key]: total_vulnerabilities.append([package, version]) # save all dependencies in the database add_scan_vul(scan.id, package, version, response[key], session) session.commit() logger.info('saved {vulnerabilities} vulnerabilities for package {package}:{version}'.format( vulnerabilities=len(response), package=package, version=version)) [get_response(i, scan_dep) for i, scan_dep in enumerate(scan_deps)] scan.total_vulnerabilities = len(total_vulnerabilities) update_scan_state(scan, ScanState.DONE, session) session.commit() # After the merge we remove the folder with the scan source scan_dir = os.path.join(SHARED_VOLUME_PATH, scan_id) try: shutil.rmtree(scan_dir) except IOError as e: logger.error("Error while removing tmp dir: {} - {}".format( scan_dir, e )) if project.hook_type != ProjectHookType.NONE.name: # launch notify task logger.debug('{} launch notify task for project.hook_type'.format(scan.id)) notify_results.delay(scan.id)
def post_project(): """Adds a project to the database It receive a Project in the body as a json object and tries to create the project in the database Example: Body {"repo": "http://google.com"} :return codes: 201 on success 400 on errors 409 on a duplicate repo """ data = request.get_json() if not data: return api_error_response('invalid payload'), 400 repo = data.get('repo', None) if repo is None or repo == '': return api_error_response('missing repo'), 400 else: data.pop('repo') # repo should not be present in data name = data.get('name', None) if name is None or name == '': name = repo.split('/')[-1] if data.get('name'): data.pop('name') # name should not be present in data email = data.get('email', None) if email is not None: hook_type = ProjectHookType.EMAIL.name hook_data = {"email": email} else: hook_type = ProjectHookType.NONE.name hook_data = {} with db.session_scope() as session: try: project = project_manager.add_project(repo, name, session, hook_type=hook_type, hook_data=hook_data, **data) session.commit() except Exception as exc: session.rollback() if 'unique constraint "project_repo_key"' in exc.args[0]: return api_error_response('unique constraint project repo {}'.format(repo)), 409 else: return api_error_response(exc.args[0]), 400 return jsonify(project.to_dict()), 201
def post_scan(): """Add a scan on the database Add a scan language on existing project Example: Body { "project_id": "00001", "lang": "javascript", "branch": "develop" //Optional } :return codes: 201 on success 400 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 project_id = get_required_field(data, 'project_id') lang = data.get('lang', None) branch = data.get('branch', None) if branch is None or branch == '': branch = 'master' else: project = get_project(project_id, session) command = 'git ls-remote --ref {}'.format(project.repo) # if defined, limit the number of scans that can be created by a given period for the same project logger.debug(' allowed scans per period {}/{}'.format(ALLOWED_SCANS_PER_PERIOD, ALLOWED_SCANS_CHECK_PERIOD)) allowed_scan = True if ALLOWED_SCANS_PER_PERIOD > 0: previous_scans = get_num_scans_in_last_minutes(project_id, ALLOWED_SCANS_CHECK_PERIOD, session) allowed_scan = previous_scans < ALLOWED_SCANS_PER_PERIOD if allowed_scan: scan = add_scan(project_id, session, lang=lang, branch=branch) session.commit() # when the scan is added to the database, a celery task is inserted for that scan to start the process celery = Celery('deeptracy', broker=BROKER_URI) celery.send_task('prepare_scan', [scan.id]) return jsonify(scan.to_dict()), 201 else: return api_error_response('cant create more scans'), 403
def get_project(project_id): """Show Requested Project Queries and returns a project with a passed ID Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: try: project = project_manager.get_project(project_id, session) except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(project.to_dict()), 200
def get_project(project_id): """Show Requested Project Queries and returns a project with a passed ID Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: try: project = project_manager.get_project(project_id, session) except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(project.to_dict()), 200
def delete_projects(): """Remove a project on the database Tries to delete the project that you specified in the endpoint on the database :return codes: 204 on success (no content) 400 on errors """ with db.session_scope() as session: try: project_manager.delete_projects(session) session.commit() except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 400 return '', 204
def get_scans_by_project_id(project_id): """Show Requested Scans by Project Queries and returns all scans in a project with a passed ID Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: try: scans = [scan.to_dict() for scan in project_manager.get_project(project_id, session).scans] except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(scans), 200
def delete_projects(): """Remove a project on the database Tries to delete the project that you specified in the endpoint on the database :return codes: 204 on success (no content) 400 on errors """ with db.session_scope() as session: try: project_manager.delete_projects(session) session.commit() except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 400 return '', 204
def notify_patton_deltas(dependencies): scan_dep_by_project_id = {} with db.session_scope() as session: for raw_dep in dependencies: scan_deps = get_scan_by_raw_dep(raw_dep, session) for scan_dep in scan_deps: project = scan_dep.scan.project if project.id in scan_dep_by_project_id: scan_dep_by_project_id[project.id]['dependencies'].append( raw_dep) else: scan_dep_by_project_id[project.id] = { 'project': project, 'dependencies': [raw_dep] } for project_id in scan_dep_by_project_id: elem = scan_dep_by_project_id[project_id] notify_deltas(elem['project'], elem['dependencies']) logger.debug('notify vulnerabilities')
def start_scan(scan_id: str): with db.session_scope() as session: logger.info('{} START SCAN'.format(scan_id)) scan = get_scan(scan_id, session) project = scan.project logger.debug('{} for project({})'.format(scan_id, project.id)) # for the lang, get the plugins that can be run available_plugins_for_lang = get_plugins_for_lang(scan.lang, session) analysis_count = len(available_plugins_for_lang) if analysis_count < 1: update_scan_state(scan, ScanState.NO_PLUGINS_FOR_LANGUAGE, session) logger.debug('{} no plugins found for language {}'.format( scan_id, scan.lang)) raise TaskException('no plugins found for language {}'.format( scan.lang)) # when we have the lang, the number of analysis to run and the source code dir, update the scan scan.analysis_count = analysis_count scan.analysis_done = 0 scan.state = ScanState.RUNNING.name session.add(scan) session.commit() # save at this point as we need the ID for this scan # save each analysis to be ran for this scan in the database and collect its ids scan_analysis_ids = [] for plugin in available_plugins_for_lang: scan_analysis = add_scan_analysis(scan.id, plugin.id, session) session.commit( ) # Commit the session to persist the scan_analysis and get and id scan_analysis_ids.append(scan_analysis.id) # create a task for each analysis to run analyzers = [ run_analyzer.s(scan_analysis_id) for scan_analysis_id in scan_analysis_ids ] # launch all jobs chord(analyzers)(merge_results.s(scan_id=scan_id))
def get_scans_by_project_id(project_id): """Show Requested Scans by Project Queries and returns all scans in a project with a passed ID Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: try: scans = [ scan.to_dict() for scan in project_manager.get_project( project_id, session).scans ] except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(scans), 200
def patch_project_email(project_id): """Update the user email for the Project Update the email for the project with project_id Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 email = data.get('email', None) if email is None or email == '': return api_error_response('missing remail'), 400 try: project = project_manager.get_project(project_id, session) hook_type = project.hook_type if project.hook_data: hook_data_dict = json.loads(project.hook_data) else: hook_data_dict = {} if hook_type == ProjectHookType.NONE.name: hook_type = ProjectHookType.EMAIL.name elif hook_type == ProjectHookType.SLACK.name: hook_type = ProjectHookType.SLACK_EMAIL.name hook_data_dict['email'] = email project_manager.update_project(project_id, session, hook_type=hook_type, hook_data=hook_data_dict) except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(project.to_dict()), 200
def run_analyzer(scan_analysis_id: str) -> List[str]: with db.session_scope() as session: scan_analysis = get_scan_analysis(scan_analysis_id, session) logger.debug('{} run analyzer'.format(scan_analysis.id)) scan = scan_analysis.scan # a plugin is a function plugin = plugin_store.get_plugin(scan_analysis.plugin_id) logger.debug('{} run analyzer for plugin {}'.format(scan_analysis.id, scan_analysis.plugin_id)) results = plugin(scan.source_path) add_scan_vulnerabilities_results(scan_analysis_id, results, session) # TODO: this should be a function that calls the celery state instead of cherrypicking a counter that can lose # integrity if something wrong happen scan.analysis_done += 1 session.add(scan) serialized_results = [result.to_dict() for result in results] return serialized_results
def patch_project_email(project_id): """Update the user email for the Project Update the email for the project with project_id Example: :return codes: 200 on success 404 on errors """ with db.session_scope() as session: data = request.get_json() if not data: return api_error_response('invalid payload'), 400 email = data.get('email', None) if email is None or email == '': return api_error_response('missing remail'), 400 try: project = project_manager.get_project(project_id, session) hook_type = project.hook_type if project.hook_data: hook_data_dict = json.loads(project.hook_data) else: hook_data_dict = {} if hook_type == ProjectHookType.NONE.name: hook_type = ProjectHookType.EMAIL.name elif hook_type == ProjectHookType.SLACK.name: hook_type = ProjectHookType.SLACK_EMAIL.name hook_data_dict['email'] = email project_manager.update_project(project_id, session, hook_type=hook_type, hook_data=hook_data_dict) except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(project.to_dict()), 200
def get_vulnerabilities(scan_id): """Get scan vulnerabilities""" with db.session_scope() as session: try: scan_vulnerabilities = [scan_vulnerability.to_dict() for scan_vulnerability in get_scan_vulnerabilities(scan_id, session)] response = [] def fillResponse(scan_vulnerability): vulns = get_vulns_for_cpe(scan_vulnerability['cpe'], session) scan_dep = get_scan_dep_by_id(scan_vulnerability['scan_dep_id'], session) return [response.append( { 'library': scan_dep.library, 'version': scan_dep.version, 'cpe': vuln.cpe, 'cve': vuln.cve }) for vuln in vulns] [ fillResponse(scan_vulnerability) for scan_vulnerability in scan_vulnerabilities] except Exception as exc: return api_error_response(exc.args[0]), 404 return jsonify(response)
def delete_project(project_id): """Remove a project on the database Tries to delete the project that you specified in the endpoint on the database :return codes: 204 on success (no content) 404 on errors (not found) """ with db.session_scope() as session: project = session.query(Project).get(project_id) try: if project: project_manager.delete_project(project_id, session) session.commit() else: return api_error_response('project not found'), 404 except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 404 return '', 204
def delete_project(project_id): """Remove a project on the database Tries to delete the project that you specified in the endpoint on the database :return codes: 204 on success (no content) 404 on errors (not found) """ with db.session_scope() as session: project = session.query(Project).get(project_id) try: if project: project_manager.delete_project(project_id, session) session.commit() else: return api_error_response('project not found'), 404 except Exception as exc: session.rollback() return api_error_response(exc.args[0]), 404 return '', 204