def admin_reports_generic(report_getter: Callable[[], Dict[str, Any]]) -> Any: if not flask.session.get('admin'): return unauthorized() if flask.request.method == 'POST': id_ = flask.request.form.get('id') reply = flask.request.form.get('reply', '') action = flask.request.form.get('action', None) if action == 'delete': get_db().delete_report(id_) flask.flash('Report removed succesfully', 'success') return flask.redirect(url_for_self()) if action == 'accept': get_db().update_report(id_, reply, True) elif action == 'reject': get_db().update_report(id_, reply, False) else: get_db().update_report(id_, reply, None) flask.flash('Report updated succesfully', 'success') return flask.redirect(url_for_self()) return flask.render_template('admin-reports.html', reports=report_getter())
def experimental() -> Any: if flask.request.method == 'POST': enabled = flask.request.form.get('experimental') == 'enable' flask.session['experimental'] = enabled flask.flash(f'Experimental mode {"enabled" if enabled else "disabled"}', 'success') return flask.redirect(url_for_self(), 302) return flask.render_template('experimental.html')
def tool_project_by() -> Any: repo = flask.request.args.get('repo') name_type = flask.request.args.get('name_type') name = flask.request.args.get('name') noautoresolve = bool(flask.request.args.get('noautoresolve')) target_page = None for allowed_target_page in _ALLOWED_TARGET_PAGES: if allowed_target_page.endpoint == flask.request.args.get( 'target_page'): target_page = allowed_target_page break template_url = None if repo and name_type and target_page: if not repometadata[repo]['family'] in _ALLOWED_FAMILIES: flask.abort(403) elif name: targets = [] for project in get_db().get_projects_by_name(repo=repo, name_type=name_type, name=name): possible_args = {'name': project, 'repo': repo} real_args = {k: possible_args[k] for k in target_page.args} targets.append( (project, flask.url_for(target_page.endpoint, **real_args))) if not targets: flask.abort(404) elif noautoresolve and len(targets) > 1: return flask.render_template( 'project-by-ambiguity.html', targets=targets, ) else: return flask.redirect(targets[0][1], 302) else: args = { k: v for k, v in flask.request.args.items() if k in _EXTRA_ALLOWED_ARGS | {'repo', 'name_type', 'noautoresolve', 'target_page'} } template_url = url_for_self(**args) return flask.render_template( 'project-by.html', allowed_target_pages=_ALLOWED_TARGET_PAGES, template_url=template_url, allowed_families=_ALLOWED_FAMILIES, )
def handle_cpe_request() -> Any: effname = flask.request.form.get('effname', '').strip() vendor = flask.request.form.get('cpe_vendor', '').strip() product = flask.request.form.get('cpe_product', '').strip() def have_all_attrs() -> bool: if not effname: flask.flash('Project name not specified', 'danger') elif not vendor: flask.flash('CPE vendor not specified', 'danger') elif not product: flask.flash('CPE product not specified', 'danger') else: return True return False if flask.request.form.get('action') == 'add': if have_all_attrs(): try: get_db().add_manual_cpe(effname, vendor, product) flask.flash(f'Manual CPE {vendor}:{product} added for {effname}', 'success') except psycopg2.errors.UniqueViolation: flask.flash(f'Manual CPE {vendor}:{product} already exists for {effname}', 'danger') elif flask.request.form.get('action') == 'remove': get_db().remove_manual_cpe(effname, vendor, product) flask.flash(f'Manual CPE {vendor}:{product} removed for {effname}', 'success') elif flask.request.form.get('action') == 'autoadd': if not effname: flask.flash('Project name not specified', 'danger') else: added = get_db().auto_add_manual_cpes(effname) if added: cpes = ', '.join(f'{vendor}:{product}' for vendor, product in added) flask.flash(f'{len(added)} manual CPE(s) {cpes} autoadded for {effname}', 'success') else: flask.flash(f'No manual CPE(s) for {effname} autoadded', 'warning') elif flask.request.form.get('action') == 'redirect': if have_all_attrs(): redirs = get_db().get_project_redirects(effname) if len(redirs) == 0: flask.flash(f'No redirects found for {effname}', 'danger') elif len(redirs) > 1: flask.flash(f'Redirect for {effname} leads to multiple projects {", ".join(redirs)}, cannot resolve', 'danger') else: try: get_db().modify_manual_cpe(effname, vendor, product, redirs[0]) flask.flash(f'Manual CPE {vendor}:{product} for {effname} moved to {redirs[0]}', 'success') except psycopg2.errors.UniqueViolation: flask.flash(f'Failed to move CPE {vendor}:{product} for {effname} to {redirs[0]} (target binding already exists?)', 'danger') return flask.redirect(url_for_self(), 302)
def tool_project_by() -> Response: repo = flask.request.args.get('repo') name_type = flask.request.args.get('name_type') name = flask.request.args.get('name') noautoresolve = bool(flask.request.args.get('noautoresolve')) target_page = None for allowed_target_page in _ALLOWED_TARGET_PAGES: if allowed_target_page.endpoint == flask.request.args.get( 'target_page'): target_page = allowed_target_page break template_url = None if repo and name_type and target_page: if repo not in repometadata.active_names(): return (flask.render_template('project-by-failed.html', reason='no_repo'), 404) elif not repometadata[repo]['family'] in _ALLOWED_FAMILIES: return (flask.render_template('project-by-failed.html', reason='disallowed_repo'), 403) elif name: targets = [] for project in get_db().get_projects_by_name(repo=repo, name_type=name_type, name=name): possible_args = {'name': project, 'repo': repo} real_args = {k: possible_args[k] for k in target_page.args} targets.append( (project, flask.url_for(target_page.endpoint, **real_args))) if not targets: return (flask.render_template('project-by-failed.html', reason='no_package'), 404) elif noautoresolve and len(targets) > 1: if target_page.type_ == EndpointType.JSON: return ( json.dumps({ '_comment': 'Ambiguous redirect, multiple target projects are possible', 'targets': {project: url for project, url in targets} }), 300, { 'Content-type': 'application/json' }, ) else: return (flask.render_template( 'project-by-ambiguity.html', targets=targets, ), 300) else: return flask.redirect(targets[0][1], 302) else: args = { k: v for k, v in flask.request.args.items() if k in _EXTRA_ALLOWED_ARGS | {'repo', 'name_type', 'noautoresolve', 'target_page'} } template_url = url_for_self(**args) return flask.render_template( 'project-by.html', allowed_target_pages=_ALLOWED_TARGET_PAGES, template_url=template_url, allowed_families=_ALLOWED_FAMILIES, )
flask.flash(f'No redirects found for {effname}', 'danger') elif len(redirs) > 1: flask.flash(f'Redirect for {effname} leads to multiple projects {", ".join(redirs)}, cannot automatically resolve', 'danger') elif not (removed_cpes := get_db().remove_manual_cpe(effname, **cpe_args)): # if we cannot remove old redirect, something is wrong, don't continue flask.flash(f'Cannot remove CPE {format_cpe(cpe_args)} for {effname}', 'danger') elif not (added_cpes := get_db().add_manual_cpe(redirs[0], **cpe_args)): # we may fail to add target CPE if it already exists, this is normal flask.flash(f'Cound not add {format_cpe(cpe_args)} for {redirs[0]}, already exists', 'warning') for cpe in added_cpes: flask.flash(f'CPE {format_cpe(cpe)} added for {cpe["effname"]}', 'success') for cpe in removed_cpes: flask.flash(f'CPE {format_cpe(cpe)} removed for {cpe["effname"]}', 'success') return flask.redirect(url_for_self(), 302) @ViewRegistrar('/admin/cpes', methods=['GET', 'POST']) def admin_cpes() -> Response: if not flask.session.get('admin'): return unauthorized() if flask.request.method == 'POST': if (response := handle_cpe_request()) is not None: return response return flask.render_template( 'admin-cpes.html', cpes=get_db().get_manual_cpes() )