Esempio n. 1
0
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())
Esempio n. 2
0
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')
Esempio n. 3
0
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,
    )
Esempio n. 4
0
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)
Esempio n. 5
0
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,
    )
Esempio n. 6
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 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()
    )