Mercurial > farol > farol
diff farol/producttree.py @ 0:4a9f23230eba
Initial Release
author | Benoît Allard <benoit.allard@greenbone.net> |
---|---|
date | Wed, 24 Sep 2014 10:07:49 +0200 |
parents | |
children | dbfe89e3c6fe |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/farol/producttree.py Wed Sep 24 10:07:49 2014 +0200 @@ -0,0 +1,263 @@ +# -*- encoding: utf-8 -*- +# Description: +# Web stuff about the ProductTree +# +# Authors: +# BenoƮt Allard <benoit.allard@greenbone.net> +# +# Copyright: +# Copyright (C) 2014 Greenbone Networks GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +"""\ +Web-stuff about the producttree +""" + +from functools import wraps + +from flask import Blueprint, render_template, redirect, url_for, abort, request, flash + +from farolluz.cvrf import (CVRFProductBranch, CVRFFullProductName, + CVRFRelationship, CVRFGroup) +from .session import document_required, get_current + +producttree = Blueprint('producttree', __name__) + +def producttree_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if get_current()._producttree is None: + flash('Operation invalid without producttree', 'warning') + return redirect(url_for('document')) + return f(*args, **kwargs) + return decorated_function + +@producttree.route('/create', methods=['POST']) +@document_required +def create(): + get_current().createProductTree() + return redirect(url_for('document')) + + +@producttree.route('/branch/<path:path>/edit', methods=['GET', 'POST']) +@document_required +@producttree_required +def edit_branch(path): + path = [int(p) for p in path.split('/')] + cvrf = get_current() + ptree = cvrf._producttree + try: + branch = cvrf._producttree.getBranch(path) + except ValueError: + abort(404) + if request.method != 'POST': + branches = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getNotTerminalBranches(branch)] + return render_template('producttree/edit_branch.j2', branch=branch, branches=branches, types=branch.TYPES) + + pbranch = ptree + if request.form['parent']: + pbranch = ptree.getBranch([int(p) for p in request.form['parent'].split('/')]) + + if pbranch is not branch.getParent(): + # We have to 're-link' the element ... + # 1. unlink + branch.unlink() + # 2. set the new parent + branch._parentbranch = pbranch + # 3. add to the Tree (again) + ptree.addBranch(branch) + + branch._type = request.form['type'] + branch._name = request.form['name'] + return redirect(url_for('document')) + +@producttree.route('/branch/add', methods=['GET', 'POST']) +@document_required +@producttree_required +def add_branch(): + cvrf = get_current() + ptree = cvrf._producttree + if request.method != 'POST': + branches = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getNotTerminalBranches()] + return render_template('producttree/edit_branch.j2', branch=CVRFProductBranch('', '', ptree), action='Add', branches=branches, types=CVRFProductBranch.TYPES) + + pbranch = ptree + if request.form['parent']: + pbranch = ptree.getBranch([int(p) for p in request.form['parent'].split('/')]) + branch = CVRFProductBranch(request.form['type'], request.form['name'], pbranch) + ptree.addBranch(branch) + return redirect(url_for('document')) + +@producttree.route('/product/<productid>') +@document_required +@producttree_required +def view_product(productid): + cvrf = get_current() + try: + product = cvrf.getProductForID(productid) + except IndexError: + abort(404) + return render_template('producttree/view_product.j2', product=product, cvrf=cvrf) + +@producttree.route('/product/<productid>/edit', methods=['GET', 'POST']) +@document_required +@producttree_required +def edit_product(productid): + cvrf = get_current() + ptree = cvrf._producttree + try: + product = cvrf.getProductForID(productid) + except KeyError: + abort(404) + + if request.method != 'POST': + current_rel = '' + if product.isRelationship(): + current_rel = str(ptree._relationships.index(product.getCurrentRelationship())) + leaves = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getOrphanedBranches(product)] + rels = [('', '')] + [(ptree.getNameOfRelationship(r), str(i)) for i, r in ptree.getOrphanedRelationships(product)] + return render_template('producttree/edit_product.j2', product=product, action='Update', orphaned_leaves=leaves, orphaned_relationships=rels, current_rel=current_rel) + + if request.form['parent_branch'] and request.form['parent_relationship']: + flash('Cannot set a parent branch and parent relationship', 'danger') + return redirect(url_for('.edit_product', productid=productid)) + + oldp = product._parent + if request.form['parent_branch']: + pbranch = ptree.getBranch([int(p) for p in request.form['parent_branch'].split('/')]) + if pbranch is not oldp: + # Gonna be funny, needs re-link + product.unlink() + product._parent = pbranch + ptree.addProduct(product) + elif request.form['parent_relationship']: + prel = ptree._relationships[int(request.form['parent_relationship'])] + if prel is not oldp: + product.unlink() + product._parent = prel + ptree.addProduct(product) + else: + if ptree is not oldp: + product.unlink() + product._parent = ptree + ptree.addProduct(product) + + product._productid = request.form['productid'] + product._name = request.form['name'] + product._cpe = request.form['cpe'] or None + return redirect(url_for('document')) + +@producttree.route('/product/add', methods=['GET', 'POST']) +@document_required +@producttree_required +def add_product(): + cvrf = get_current() + ptree = cvrf._producttree + + if request.method != 'POST': + product=CVRFFullProductName('', '', ptree) + leaves = [('', '')] + [(b.getName(), b.getPath(True)) for b in ptree.getOrphanedBranches()] + rels = [('', '')] + [(ptree.getNameOfRelationship(r), str(i)) for i, r in ptree.getOrphanedRelationships()] + return render_template('producttree/edit_product.j2', product=product, action='Add', orphaned_leaves=leaves, orphaned_relationships=rels, current_rel='') + + if request.form['parent_branch'] and request.form['parent_relationship']: + flash('Cannot set a parent branch and parent relationship', 'danger') + return redirect(url_for('.edit_product', productid=productid)) + + parent = ptree + if request.form['parent_branch']: + parent = ptree.getBranch([int(p) for p in request.form['parent_branch'].split('/')]) + elif request.form['parent_relationship']: + parent = ptree._relationships[int(request.form['parent_relationship'])] + + product = CVRFFullProductName(request.form['productid'], request.form['name'], parent, request.form['cpe'] or None) + ptree.addProduct(product) + return redirect(url_for('document')) + +@producttree.route('/relationship/<int:index>/edit', methods=['GET', 'POST']) +@document_required +@producttree_required +def edit_relationship(index): + cvrf = get_current() + ptree = cvrf._producttree + try: + rel = ptree._relationships[index] + except IndexError: + abort(404) + + if request.method != 'POST': + return render_template('producttree/edit_relationship.j2', productreference=rel._productreference, relationtype=rel._relationtype, relatestoproductreference=rel._relatestoproductreference, types=rel.TYPES) + + rel._productreference = request.form['productreference'] + rel._relationtype = request.form['relationtype'] + rel._relatestoproductreference = request.form['relatestoproductreference'] + return redirect(url_for('document')) + +@producttree.route('/relationship/add', methods=['GET', 'POST']) +@document_required +@producttree_required +def add_relationship(): + cvrf = get_current() + ptree = cvrf._producttree + if len(ptree._products) < 2: + flash('You need to have at least two products to create a relationship', 'warning') + return redirect(url_for('.add_product')) + + if request.method != 'POST': + return render_template('producttree/edit_relationship.j2', action='Add', types=CVRFRelationship.TYPES) + + prodid1 = request.form['productreference'] + prodid2 = request.form['relatestoproductreference'] + + if prodid1 == prodid2: + flash('You cannot create a relationship with the same product twice', 'danger') + return redirect(url_for('.add_relationship')) + + rel = CVRFRelationship(prodid1, request.form['relationtype'], prodid2) + ptree.addRelationship(rel) + return redirect(url_for('document')) + +@producttree.route('/group/<groupid>/edit', methods=['GET', 'POST']) +@document_required +@producttree_required +def edit_group(groupid): + try: + group = get_current().getGroupForID(groupid) + except KeyError: + abort(404) + if request.method != 'POST': + return render_template('producttree/edit_group.j2', groupid=group._groupid, description=group._description, productids=group._productids) + + group._groupid = request.form['groupid'] + group.setDescription(request.form['description'] or None) + group._productids = [] + for productid in request.form.getlist('products'): + group.addProductID(productid) + return redirect(url_for('document')) + +@producttree.route('/group/add', methods=['GET', 'POST']) +@document_required +@producttree_required +def add_group(): + if request.method != 'POST': + return render_template('producttree/edit_group.j2', action='Add') + + group = CVRFGroup(request.form['groupid']) + group.setDescription(request.form['description'] or None) + for productid in request.form.getlist('products'): + group.addProductID(productid) + get_current()._producttree.addGroup(group) + return redirect(url_for('document'))