Exemplo n.º 1
0
def package_orphan(package, collection):
    ''' Gives the possibility to orphan or take a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    for acl in package_acl:
        if acl.collection.branchname == collection:
            try:
                pkgdblib.update_pkg_poc(
                    session=SESSION,
                    pkg_name=package.name,
                    pkg_branch=acl.collection.branchname,
                    pkg_poc='orphan',
                    user=flask.g.fas_user
                )
                flask.flash(
                    'You are no longer point of contact on branch: %s'
                    % collection)
            except pkgdblib.PkgdbException, err:
                flask.flash(str(err), 'error')
                SESSION.rollback()
            break
Exemplo n.º 2
0
def package_retire(package, collection):
    ''' Gives the possibility to orphan or take a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    for acl in package_acl:
        if acl.collection.branchname == collection:
            if acl.point_of_contact == 'orphan':
                try:
                    pkgdblib.update_pkg_status(
                        session=SESSION,
                        pkg_name=package.name,
                        pkg_branch=acl.collection.branchname,
                        status='Retired',
                        user=flask.g.fas_user)
                    flask.flash('This package has been retired on branch: %s' %
                                collection)
                except pkgdblib.PkgdbException, err:
                    flask.flash(str(err), 'error')
                    SESSION.rollback()
                break
            else:
                flask.flash('This package has not been orphaned on '
                            'branch: %s' % collection)
Exemplo n.º 3
0
def package_request_branch(namespace, package, full=True):
    ''' Gives the possibility to request a new branch for this package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    branches = [
        pkg.collection.branchname
        for pkg in package_acl
        if pkg.collection.status != 'EOL'
    ]

    collections = pkgdb2.lib.search_collection(
        SESSION, '*', 'Under Development')
    collections.extend(pkgdb2.lib.search_collection(SESSION, '*', 'Active'))

    # List the possible branches that this package does not already have.
    branches_possible = [
        collec.branchname
        for collec in collections
        if collec.branchname not in branches]

    # Further limit that list to only the branches allowed for this namespace.
    namespace_policy = APP.config.get('PKGDB2_NAMESPACE_POLICY')
    policy = namespace_policy.get(pkg.package.namespace)
    if policy:
        branches_possible = [b for b in branches_possible if b in policy]

    form = pkgdb2.forms.BranchForm(collections=branches_possible)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                msg = pkgdblib.add_new_branch_request(
                    session=SESSION,
                    namespace=package.namespace,
                    pkg_name=package.name,
                    clt_to=branch,
                    user=flask.g.fas_user)
                SESSION.commit()
                flask.flash(msg)
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except SQLAlchemyError, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(
                    'Could not save the request to the database for '
                    'branch: %s' % branch, 'error')
                SESSION.rollback()
Exemplo n.º 4
0
def package_orphan(package, collection):
    ''' Gives the possibility to orphan or take a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    for acl in package_acl:
        if acl.collection.branchname == collection:
            try:
                pkgdblib.update_pkg_poc(session=SESSION,
                                        pkg_name=package.name,
                                        pkg_branch=acl.collection.branchname,
                                        pkg_poc='orphan',
                                        user=flask.g.fas_user)
                flask.flash(
                    'You are no longer point of contact on branch: %s' %
                    collection)
            except pkgdblib.PkgdbException, err:
                flask.flash(str(err), 'error')
                SESSION.rollback()
            break
Exemplo n.º 5
0
def package_retire(package, full=True):
    ''' Gives the possibility to orphan or take a package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, package)
        package = pkgdblib.search_package(SESSION, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    if not is_pkgdb_admin(flask.g.fas_user):
        flask.flash(
            'Only Admins are allowed to retire package here, '
            'you should use `fedpkg retire`.', 'errors')
        return flask.redirect(
            flask.url_for('.package_info', package=package.name))

    collections = [
        acl.collection.branchname for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Orphaned'
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.update_pkg_status(
                            session=SESSION,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            status='Retired',
                            user=flask.g.fas_user)
                        flask.flash(
                            'This package has been retired on branch: %s' %
                            acl.collection.branchname)
                    except pkgdblib.PkgdbException, err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                        APP.logger.exception(err)
                else:  # pragma: no cover
                    flask.flash('This package has not been orphaned on '
                                'branch: %s' % acl.collection.branchname)

        try:
            SESSION.commit()
        # Keep it in, but normally we shouldn't hit this
        except pkgdblib.PkgdbException, err:  # pragma: no cover
            # We should never hit this
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash(str(err), 'error')
Exemplo n.º 6
0
def package_retire(package, collection):
    ''' Gives the possibility to orphan or take a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    for acl in package_acl:
        if acl.collection.branchname == collection:
            if acl.point_of_contact == 'orphan':
                try:
                    pkgdblib.update_pkg_status(
                        session=SESSION,
                        pkg_name=package.name,
                        pkg_branch=acl.collection.branchname,
                        status='Retired',
                        user=flask.g.fas_user
                    )
                    flask.flash(
                        'This package has been retired on branch: %s'
                        % collection)
                except pkgdblib.PkgdbException, err:
                    flask.flash(str(err), 'error')
                    SESSION.rollback()
                break
            else:
                flask.flash(
                    'This package has not been orphaned on '
                    'branch: %s' % collection)
Exemplo n.º 7
0
def package_orphan(namespace, package, full=True):
    ''' Gives the possibility to orphan or take a package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Approved'
        and (
            is_pkgdb_admin(flask.g.fas_user)
            or acl.point_of_contact == flask.g.fas_user.username
            or (
                acl.point_of_contact.startswith('group::') and
                is_pkg_admin(
                    SESSION, flask.g.fas_user, namespace, package.name)
            )
        )
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                pkgdblib.update_pkg_poc(
                    session=SESSION,
                    namespace=namespace,
                    pkg_name=package.name,
                    pkg_branch=branch,
                    pkg_poc='orphan',
                    user=flask.g.fas_user
                )

                flask.flash(
                    'You are no longer point of contact on branch: %s'
                    % branch)
            except pkgdblib.PkgdbBugzillaException, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
Exemplo n.º 8
0
def request_acl(namespace, package):
    ''' Request acls for a specific package. '''

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
    ]

    pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']

    form = pkgdb2.forms.RequestAclPackageForm(collections=collections,
                                              pkg_acl_list=pkg_acl)
    if form.validate_on_submit():
        pkg_branchs = form.branches.data
        pkg_acls = form.acl.data

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                acl_status = 'Awaiting Review'
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'
                elif 'packager' not in flask.g.fas_user.groups:
                    flask.flash(
                        'You must be a packager to apply to the'
                        ' ACL: %s on %s' % (acl, collec), 'errors')
                    continue

                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package.name,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
            return flask.redirect(
                flask.url_for('.package_info',
                              namespace=package.namespace,
                              package=package.name))

        except pkgdblib.PkgdbException, err:
            SESSION.rollback()
            flask.flash(str(err), 'error')
Exemplo n.º 9
0
def request_acl(package):
    ''' Request acls for a specific package. '''

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, package)
        package = pkgdblib.search_package(SESSION, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
    ]

    pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']

    form = pkgdb2.forms.RequestAclPackageForm(
        collections=collections,
        pkg_acl_list=pkg_acl
    )
    if form.validate_on_submit():
        pkg_branchs = form.branches.data
        pkg_acls = form.acl.data

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                acl_status = 'Awaiting Review'
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'
                elif 'packager' not in flask.g.fas_user.groups:
                    flask.flash(
                        'You must be a packager to apply to the'
                        ' ACL: %s on %s' % (acl, collec), 'errors')
                    continue

                pkgdblib.set_acl_package(
                    SESSION,
                    pkg_name=package.name,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
            return flask.redirect(
                flask.url_for('.package_info',
                              package=package.name))
        except pkgdblib.PkgdbException, err:
            SESSION.rollback()
            flask.flash(str(err), 'error')
Exemplo n.º 10
0
def package_take(namespace, package, full=True):
    ''' Make someone Point of contact of an orphaned package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Orphaned'
    ]

    if not collections:
        flask.flash('No branches orphaned found', 'error')
        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                pkgdblib.unorphan_package(
                    session=SESSION,
                    namespace=package.namespace,
                    pkg_name=package.name,
                    pkg_branch=branch,
                    pkg_user=flask.g.fas_user.username,
                    user=flask.g.fas_user
                )
                SESSION.commit()
                flask.flash('You have taken the package %s on branch %s' % (
                    package.name, branch))
            except pkgdblib.PkgdbBugzillaException, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
Exemplo n.º 11
0
def package_unretire(package, full=True):
    ''' Asks an admin to unretire the package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, package)
        package = pkgdblib.search_package(SESSION, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Retired'
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.add_unretire_request(
                            session=SESSION,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            user=flask.g.fas_user,
                        )
                        flask.flash(
                            'Admins have been asked to un-retire branch: %s'
                            % acl.collection.branchname)
                    except pkgdblib.PkgdbException, err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                    except SQLAlchemyError, err:
                        SESSION.rollback()
                        flask.flash(
                            'Could not save the request for branch: %s, has '
                            'it already been requested?'
                            % acl.collection.branchname, 'error')
                else:  # pragma: no cover
                    flask.flash(
                        'This package is not orphaned on branch: %s'
                        % acl.collection.branchname)
Exemplo n.º 12
0
def package_request_branch(namespace, package, full=True):
    ''' Gives the possibility to request a new branch for this package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    branches = [
        pkg.collection.branchname for pkg in package_acl
        if pkg.collection.status != 'EOL'
    ]

    collections = pkgdb2.lib.search_collection(SESSION, '*',
                                               'Under Development')
    collections.extend(pkgdb2.lib.search_collection(SESSION, '*', 'Active'))
    branches_possible = [
        collec.branchname for collec in collections
        if collec.branchname not in branches
    ]

    form = pkgdb2.forms.BranchForm(collections=branches_possible)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                msg = pkgdblib.add_new_branch_request(
                    session=SESSION,
                    namespace=package.namespace,
                    pkg_name=package.name,
                    clt_to=branch,
                    user=flask.g.fas_user)
                SESSION.commit()
                flask.flash(msg)
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except SQLAlchemyError, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(
                    'Could not save the request to the database for '
                    'branch: %s' % branch, 'error')
                SESSION.rollback()
Exemplo n.º 13
0
def package_take(namespace, package, full=True):
    ''' Make someone Point of contact of an orphaned package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Orphaned'
    ]

    if not collections:
        flask.flash('No branches orphaned found', 'error')
        return flask.redirect(
            flask.url_for('.package_info',
                          namespace=package.namespace,
                          package=package.name))

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                pkgdblib.unorphan_package(session=SESSION,
                                          namespace=package.namespace,
                                          pkg_name=package.name,
                                          pkg_branch=branch,
                                          pkg_user=flask.g.fas_user.username,
                                          user=flask.g.fas_user)
                SESSION.commit()
                flask.flash('You have taken the package %s on branch %s' %
                            (package.name, branch))
            except pkgdblib.PkgdbBugzillaException, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
Exemplo n.º 14
0
def package_unretire(package, full=True):
    ''' Asks an admin to unretire the package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, package)
        package = pkgdblib.search_package(SESSION, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Retired'
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.add_unretire_request(
                            session=SESSION,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            user=flask.g.fas_user,
                        )
                        flask.flash(
                            'Admins have been asked to un-retire branch: %s' %
                            acl.collection.branchname)
                    except pkgdblib.PkgdbException, err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                    except SQLAlchemyError, err:
                        SESSION.rollback()
                        flask.flash(
                            'Could not save the request for branch: %s, has '
                            'it already been requested?' %
                            acl.collection.branchname, 'error')
                else:  # pragma: no cover
                    flask.flash('This package is not orphaned on branch: %s' %
                                acl.collection.branchname)
Exemplo n.º 15
0
def package_orphan(namespace, package, full=True):
    ''' Gives the possibility to orphan or take a package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    collections = [
        acl.collection.branchname for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Approved' and (
            is_pkgdb_admin(flask.g.fas_user)
            or acl.point_of_contact == flask.g.fas_user.username or
            (acl.point_of_contact.startswith('group::') and is_pkg_admin(
                SESSION, flask.g.fas_user, namespace, package.name)))
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                pkgdblib.update_pkg_poc(session=SESSION,
                                        namespace=namespace,
                                        pkg_name=package.name,
                                        pkg_branch=branch,
                                        pkg_poc='orphan',
                                        user=flask.g.fas_user)

                flask.flash(
                    'You are no longer point of contact on branch: %s' %
                    branch)
            except pkgdblib.PkgdbBugzillaException, err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
Exemplo n.º 16
0
def package_info(package):
    ''' Display the information about the specified package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    planned_acls = set(pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl'])

    branches = set()
    commit_acls = {}
    watch_acls = {}
    admins = {}
    pending_admins = {}
    pocs = {}
    committers = []

    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue

        collection_name = '%s %s' % (pkg.collection.name,
                                     pkg.collection.version)

        branches.add(collection_name)

        if pkg.point_of_contact not in pocs:
            pocs[pkg.point_of_contact] = set()
        pocs[pkg.point_of_contact].add(collection_name)

        for acl in pkg.acls:

            if acl.acl == 'approveacls' and acl.status == 'Approved':
                if acl.fas_name not in admins:
                    admins[acl.fas_name] = set()
                admins[acl.fas_name].add(collection_name)
            elif acl.acl == 'approveacls' and acl.status == 'Awaiting Review':
                if acl.fas_name not in pending_admins:
                    pending_admins[acl.fas_name] = set()
                pending_admins[acl.fas_name].add(collection_name)

            if acl.acl == 'commit':
                dic = commit_acls
                if acl.status == 'Approved':
                    committers.append(acl.fas_name)
            elif acl.acl.startswith('watch') and acl.status == 'Approved':
                dic = watch_acls
            else:  # pragma: no cover  -- pass isn't `covered` by coverage
                # We managed approveacls earlier
                continue

            if acl.fas_name not in dic:
                dic[acl.fas_name] = {}
            if collection_name not in dic[acl.fas_name]:
                dic[acl.fas_name][collection_name] = {}

            dic[acl.fas_name][collection_name][acl.acl] = \
                acl.status

        for aclname in planned_acls:
            for user in commit_acls:
                if collection_name in commit_acls[user] and \
                        aclname not in commit_acls[user][collection_name]:
                    commit_acls[user][collection_name][aclname] = None

        for aclname in planned_acls:
            for user in watch_acls:
                if collection_name in watch_acls[user] and \
                        aclname not in watch_acls[user][collection_name]:
                    watch_acls[user][collection_name][aclname] = None

    statuses = set([
        listing.status for listing in package.sorted_listings
        if listing.collection.status != 'EOL'
    ])

    collections = pkgdb2.lib.search_collection(SESSION, '*',
                                               'Under Development')
    collections.extend(pkgdb2.lib.search_collection(SESSION, '*', 'Active'))
    branches_possible = [
        collec.branchname for collec in collections
        if '%s %s' % (collec.name, collec.version) not in branches
    ]

    requester = False
    if is_authenticated():
        for req in package.requests:
            if req.user == flask.g.fas_user.username:
                requester = True
                break

    return flask.render_template(
        'package.html',
        package=package,
        commit_acls=commit_acls,
        watch_acls=watch_acls,
        pocs=pocs,
        admins=admins,
        statuses=statuses,
        pending_admins=pending_admins,
        branches=branches,
        branches_possible=branches_possible,
        committers=committers,
        form=pkgdb2.forms.ConfirmationForm(),
        requester=requester,
    )
Exemplo n.º 17
0
    def test_api_package_unorphan(self, login_func, mock_func):
        """ Test the api_package_unorphan function.  """
        login_func.return_value = None

        # Redirect as you are not a packager
        user = FakeFasUser()
        user.groups = []

        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/')
            self.assertEqual(output.status_code, 302)

        user = FakeFasUser()
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/')
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "Invalid input submitted",
                    "error_detail": [
                        "pkgnames: This field is required.",
                        "branches: This field is required.",
                        "poc: This field is required.",
                    ],
                    "output": "notok"
                }
            )

        mock_func.get_packagers.return_value = ['test']

        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/', data=data)
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "No package found by this name",
                    "output": "notok"
                }
            )

        create_package_acl(self.session)
        mock_func.log.return_value = ''

        # Unorphan a not-orphaned package
        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/', data=data)
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "Package \"guake\" is not orphaned on f18",
                    "output": "notok"
                }
            )

        # Orphan the package
        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/orphan/', data=data)
            self.assertEqual(output.status_code, 200)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "messages": ["", ""],
                    "output": "ok"
                }
            )
            pkg_acl = pkgdblib.get_acl_package(self.session, 'guake')
            self.assertEqual(pkg_acl[0].collection.branchname, 'f18')
            self.assertEqual(pkg_acl[0].package.name, 'guake')
            self.assertEqual(pkg_acl[0].point_of_contact, 'orphan')
            self.assertEqual(pkg_acl[0].status, 'Orphaned')

            self.assertEqual(pkg_acl[1].collection.branchname, 'master')
            self.assertEqual(pkg_acl[1].package.name, 'guake')
            self.assertEqual(pkg_acl[1].point_of_contact, 'orphan')
            self.assertEqual(pkg_acl[1].status, 'Orphaned')

        # Unorphan the package for someone else
        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/', data=data)
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "You are not allowed to update ACLs of someone "
                    "else.",
                    "output": "notok"
                }
            )

        mock_func.get_packagers.return_value = ['pingou']

        # Unorphan the package
        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'pingou',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/unorphan/', data=data)
            self.assertEqual(output.status_code, 200)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "messages": [
                        "Package guake has been unorphaned on f18 by pingou",
                        "Package guake has been unorphaned on master by pingou"
                    ],
                    "output": "ok"
                }
            )

            pkg_acl = pkgdblib.get_acl_package(self.session, 'guake')
            self.assertEqual(pkg_acl[0].collection.branchname, 'f18')
            self.assertEqual(pkg_acl[0].package.name, 'guake')
            self.assertEqual(pkg_acl[0].point_of_contact, 'pingou')
            self.assertEqual(pkg_acl[0].status, 'Approved')

            self.assertEqual(pkg_acl[1].collection.branchname, 'master')
            self.assertEqual(pkg_acl[1].package.name, 'guake')
            self.assertEqual(pkg_acl[1].point_of_contact, 'pingou')
            self.assertEqual(pkg_acl[1].status, 'Approved')
Exemplo n.º 18
0
    def test_api_package_orphan(self, login_func, mock_func):
        """ Test the api_package_orphan function.  """
        login_func.return_value = None

        # Redirect as you are not a packager
        user = FakeFasUser()
        user.groups = []

        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/orphan/')
            self.assertEqual(output.status_code, 302)

        user = FakeFasUser()
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/orphan/')
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "Invalid input submitted",
                    "error_detail": [
                        "pkgnames: This field is required.",
                        "branches: This field is required.",
                    ],
                    "output": "notok"
                }
            )

        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/orphan/', data=data)
            self.assertEqual(output.status_code, 500)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "error": "No package found by this name",
                    "output": "notok"
                }
            )

        create_package_acl(self.session)
        mock_func.log.return_value = ''

        data = {
            'pkgnames': 'guake',
            'branches': ['f18', 'master'],
            'poc': 'test',
        }
        with user_set(pkgdb2.APP, user):
            output = self.app.post('/api/package/orphan/', data=data)
            self.assertEqual(output.status_code, 200)
            data = json.loads(output.data)
            self.assertEqual(
                data,
                {
                    "messages": ["", ""],
                    "output": "ok"
                }
            )
            pkg_acl = pkgdblib.get_acl_package(self.session, 'guake')
            self.assertEqual(pkg_acl[0].collection.branchname, 'f18')
            self.assertEqual(pkg_acl[0].package.name, 'guake')
            self.assertEqual(pkg_acl[0].point_of_contact, 'orphan')
            self.assertEqual(pkg_acl[0].status, 'Orphaned')

            self.assertEqual(pkg_acl[1].collection.branchname, 'master')
            self.assertEqual(pkg_acl[1].package.name, 'guake')
            self.assertEqual(pkg_acl[1].point_of_contact, 'orphan')
            self.assertEqual(pkg_acl[1].status, 'Orphaned')
Exemplo n.º 19
0
def api_package_info(pkg_name=None):
    '''
Package information
-------------------
    Return information about a specific package.

    ::

        /api/package/<pkg_name>/

        /api/package/?pattern=<pkg_name>

    Accept GET queries only

    :arg pkg_name: The name of the package to retrieve the information of.
    :kwarg pkg_clt: Restricts the package information to a specific
        collection (branch).

    Sample response:

    ::

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "point_of_contact": "pingou",
              "package": {
                "status": "Approved",
                "upstream_url": null,
                "description": "Guake is a drop-down terminal for Gnome "
                             "Desktop Environment, so you just need to "
                             "press a key to invoke him,and press again "
                             "to hide."
                "summary": "Drop-down terminal for GNOME",
                "creation_date": 1385365548.0,
                "review_url": null,
                "name": "guake"
              },
              "collection": {
                "status": "Under Development",
                "branchname": "devel",
                "version": "devel",
                "name": "Fedora"
              },
              "acls": [
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchcommits"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchbugzilla"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "commit"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "approveacls"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchcommits"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchbugzilla"
                }
              ],
              "status_change": 1385366044.0
            },
            ...
          ]
        }

    '''
    httpcode = 200
    output = {}

    pkg_name = flask.request.args.get('pkg_name', pkg_name)
    pkg_clt = flask.request.args.get('pkg_clt', None)

    try:
        packages = pkgdblib.get_acl_package(
            SESSION,
            pkg_name=pkg_name,
            pkg_clt=pkg_clt
        )
        output['output'] = 'ok'
        output['packages'] = [pkg.to_json() for pkg in packages]
    except NoResultFound:
        output['output'] = 'notok'
        output['error'] = 'Package: %s not found' % pkg_name
        httpcode = 404
    except pkgdblib.PkgdbException, err:
        SESSION.rollback()
        output['output'] = 'notok'
        output['error'] = str(err)
        httpcode = 500
Exemplo n.º 20
0
def api_package_info(pkg_name=None):
    '''
Package information
-------------------
    Return information about a specific package.

    ::

        /api/package/<pkg_name>/

        /api/package/?pattern=<pkg_name>

    Accept GET queries only

    :arg pkg_name: The name of the package to retrieve the information of.
    :kwarg pkg_clt: Restricts the package information to a specific
        collection (branch).

    Sample response:

    ::

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "point_of_contact": "pingou",
              "package": {
                "status": "Approved",
                "upstream_url": null,
                "description": "Guake is a drop-down terminal for Gnome "
                             "Desktop Environment, so you just need to "
                             "press a key to invoke him,and press again "
                             "to hide."
                "summary": "Drop-down terminal for GNOME",
                "creation_date": 1385365548.0,
                "review_url": null,
                "name": "guake"
              },
              "collection": {
                "status": "Under Development",
                "branchname": "devel",
                "version": "devel",
                "name": "Fedora"
              },
              "acls": [
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchcommits"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchbugzilla"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "commit"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "approveacls"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchcommits"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchbugzilla"
                }
              ],
              "status_change": 1385366044.0
            },
            ...
          ]
        }

    '''
    httpcode = 200
    output = {}

    pkg_name = flask.request.args.get('pkg_name', pkg_name)
    pkg_clt = flask.request.args.get('pkg_clt', None)

    try:
        packages = pkgdblib.get_acl_package(SESSION,
                                            pkg_name=pkg_name,
                                            pkg_clt=pkg_clt)
        output['output'] = 'ok'
        output['packages'] = [pkg.to_json() for pkg in packages]
    except NoResultFound:
        output['output'] = 'notok'
        output['error'] = 'Package: %s not found' % pkg_name
        httpcode = 404
    except pkgdblib.PkgdbException, err:
        SESSION.rollback()
        output['output'] = 'notok'
        output['error'] = str(err)
        httpcode = 500
Exemplo n.º 21
0
def api_package_info(pkgname=None):
    '''
    Package information
    -------------------
    Return information about a specific package.

    ::

        /api/package/<pkg_name>/

        /api/package/?pkgname=<pkg_name>

    Accepts GET queries only

    :arg pkgname: The name of the package to retrieve the information of.
    :kwarg branches: Restricts the package information to one or more
        collection (branches).
    :kwarg eol: a boolean to specify whether to include results for
        EOL collections or not. Defaults to False.
        If True, it will return results for all collections (including EOL).
        If False, it will return results only for non-EOL collections.
    :kwarg acls: a boolean to specify whether to include the ACLs in the
        results. Defaults to True.
        If True, it will include the ACL of the package in the collection.
        If False, it will not include the ACL of the package in the
        collection.

    Sample response:

    ::

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "point_of_contact": "pingou",
              "critpath": False,
              "package": {
                "status": "Approved",
                "upstream_url": null,
                "description": "Guake is a drop-down terminal for Gnome "
                             "Desktop Environment, so you just need to "
                             "press a key to invoke him,and press again "
                             "to hide."
                "summary": "Drop-down terminal for GNOME",
                "creation_date": 1385365548.0,
                "review_url": null,
                "name": "guake"
              },
              "collection": {
                "status": "Under Development",
                "branchname": "master",
                "version": "devel",
                "name": "Fedora"
              },
              "acls": [
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchcommits"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchbugzilla"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "commit"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "approveacls"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchcommits"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchbugzilla"
                },
                {
                  "acl": "commit",
                  "fas_name": "group::provenpackager",
                  "status": "Approved"
                }
              ],
              "status_change": 1385366044.0
            },
            ...
          ]
        }

    '''
    httpcode = 200
    output = {}

    pkg_name = flask.request.args.get('pkgname', pkgname)
    branches = flask.request.args.getlist('branches', None)
    eol = flask.request.args.get('eol', False)
    acls = flask.request.args.get('acls', True)
    if str(acls).lower() in ['0', 'false']:
        acls = False

    try:
        packages = pkgdblib.get_acl_package(
            SESSION,
            pkg_name=pkg_name,
            pkg_clt=branches,
            eol=eol,
        )
        if not packages:
            output['output'] = 'notok'
            output['error'] = 'No package found on these branches: %s' \
                % ', '.join(branches)
            httpcode = 404
        else:
            output['output'] = 'ok'
            output['packages'] = [
                pkg.to_json(not_provenpackager=APP.config.get(
                    'PKGS_NOT_PROVENPACKAGER'),
                            acls=acls) for pkg in packages
            ]
    except NoResultFound:
        output['output'] = 'notok'
        output['error'] = 'Package: %s not found' % pkg_name
        httpcode = 404

    jsonout = flask.jsonify(output)
    jsonout.status_code = httpcode
    return jsonout
Exemplo n.º 22
0
def package_give(namespace, package, full=True):
    ''' Gives the PoC of a package to someone else. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, packagename)
        package = pkgdblib.search_package(
            SESSION, namespace, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    # Restrict the branch to the one current user is PoC of (unless admin
    # or group)
    collect_name = []
    for acl in package_acl:
        if acl.point_of_contact != flask.g.fas_user.username and \
                not is_pkgdb_admin(flask.g.fas_user) and \
                not acl.point_of_contact.startswith('group::'):
            pass
        else:
            if acl.point_of_contact.startswith('group::'):
                group = acl.point_of_contact.split('group::')[0]
                if group not in flask.g.fas_user.groups:
                    pass
            elif acl.collection.status != 'EOL':
                collect_name.append(acl.collection.branchname)

    form = pkgdb2.forms.GivePoCForm(collections=collect_name)

    acls = ['commit', 'watchbugzilla', 'watchcommits', 'approveacls']

    if form.validate_on_submit():
        collections = form.branches.data
        pkg_poc = form.poc.data
        if pkg_poc.startswith('group::'):
            acls = ['commit', 'watchbugzilla', 'watchcommits']

        try:
            for pkg_collection in collections:
                message = pkgdblib.update_pkg_poc(
                    SESSION,
                    namespace=namespace,
                    pkg_name=packagename,
                    pkg_branch=pkg_collection,
                    pkg_poc=pkg_poc,
                    user=flask.g.fas_user,
                )
                flask.flash(message)

                for acl in acls:
                    pkgdblib.set_acl_package(
                        SESSION,
                        namespace=namespace,
                        pkg_name=packagename,
                        pkg_branch=pkg_collection,
                        pkg_user=pkg_poc,
                        acl=acl,
                        status='Approved',
                        user=flask.g.fas_user
                    )

                SESSION.commit()
        except pkgdblib.exceptions.PkgdbBugzillaException as err:  # pragma: no cover
            APP.logger.exception(err)
            flask.flash(str(err), 'error')
            SESSION.rollback()
        except PkgdbException as err:
            SESSION.rollback()
            flask.flash(str(err), 'error')

        return flask.redirect(flask.url_for(
            '.package_info', namespace=namespace, package=packagename)
        )

    return flask.render_template(
        'package_give.html',
        full=full,
        form=form,
        packagename=packagename,
        namespace=namespace,
    )
Exemplo n.º 23
0
def package_info(namespace, package):
    ''' Display the information about the specified package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, packagename)
        package = pkgdblib.search_package(
            SESSION, namespace, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    planned_acls = set(
        pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl'])

    branches = set()
    commit_acls = {}
    watch_acls = {}
    admins = {}
    pending_admins = {}
    pocs = {}
    committers = []

    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue

        collection_name = '%s %s' % (
            pkg.collection.name, pkg.collection.version)

        branches.add(collection_name)

        if pkg.point_of_contact not in pocs:
            pocs[pkg.point_of_contact] = set()
        pocs[pkg.point_of_contact].add(collection_name)

        for acl in pkg.acls:

            if acl.acl == 'approveacls' and acl.status == 'Approved':
                if acl.fas_name not in admins:
                    admins[acl.fas_name] = set()
                admins[acl.fas_name].add(collection_name)
            elif acl.acl == 'approveacls' and acl.status == 'Awaiting Review':
                if acl.fas_name not in pending_admins:
                    pending_admins[acl.fas_name] = set()
                pending_admins[acl.fas_name].add(collection_name)

            if acl.acl == 'commit':
                dic = commit_acls
                if acl.status == 'Approved':
                    committers.append(acl.fas_name)
            elif acl.acl.startswith('watch') and acl.status == 'Approved':
                dic = watch_acls
            else:  # pragma: no cover  -- pass isn't `covered` by coverage
                # We managed approveacls earlier
                continue

            if acl.fas_name not in dic:
                dic[acl.fas_name] = {}
            if collection_name not in dic[acl.fas_name]:
                dic[acl.fas_name][collection_name] = {}

            dic[acl.fas_name][collection_name][acl.acl] = \
                acl.status

        for aclname in planned_acls:
            for user in commit_acls:
                if collection_name in commit_acls[user] and \
                        aclname not in commit_acls[user][collection_name]:
                    commit_acls[user][collection_name][aclname] = None

        for aclname in planned_acls:
            for user in watch_acls:
                if collection_name in watch_acls[user] and \
                        aclname not in watch_acls[user][collection_name]:
                    watch_acls[user][collection_name][aclname] = None

    statuses = set([
        listing.status
        for listing in package.sorted_listings
        if listing.collection.status != 'EOL'
    ])

    collections = pkgdb2.lib.search_collection(
        SESSION, '*', 'Under Development')
    collections.extend(pkgdb2.lib.search_collection(SESSION, '*', 'Active'))
    branches_possible = [
        collec.branchname
        for collec in collections
        if '%s %s' % (collec.name, collec.version) not in branches]

    requester = False
    if is_authenticated():
        for req in package.requests:
            if req.user == flask.g.fas_user.username:
                requester = True
                break

    return flask.render_template(
        'package.html',
        package=package,
        commit_acls=commit_acls,
        watch_acls=watch_acls,
        pocs=pocs,
        admins=admins,
        statuses=statuses,
        pending_admins=pending_admins,
        branches=branches,
        branches_possible=branches_possible,
        committers=committers,
        form=pkgdb2.forms.ConfirmationForm(),
        requester=requester,
    )
Exemplo n.º 24
0
def update_acl(namespace, package, update_acl):
    ''' Update the acls of a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, packagename)
        package = pkgdblib.search_package(
            SESSION, namespace, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    statues = pkgdblib.get_status(SESSION)
    planned_acls = set(statues['pkg_acl'])
    acl_status = list(set(statues['acl_status']))
    acl_status.insert(0, '')

    if update_acl not in planned_acls:
        flask.flash('Invalid ACL to update.', 'errors')
        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    branches = {}
    branches_inv = {}
    commit_acls = {}
    admins = {}
    committers = []

    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue

        collection_name = '%s %s' % (
            pkg.collection.name, pkg.collection.version)

        if collection_name not in branches:
            branches[collection_name] = pkg.collection.branchname

        if pkg.collection.branchname not in branches_inv:
            branches_inv[pkg.collection.branchname] = collection_name

        for acl in pkg.acls:

            if acl.acl == 'approveacls' and acl.status == 'Approved':
                if acl.fas_name not in admins:
                    admins[acl.fas_name] = set()
                admins[acl.fas_name].add(collection_name)

            if acl.acl != update_acl:
                continue

            committers.append(acl.fas_name)
            if acl.fas_name not in commit_acls:
                commit_acls[acl.fas_name] = {}
            if collection_name not in commit_acls[acl.fas_name]:
                commit_acls[acl.fas_name][collection_name] = {}

            commit_acls[acl.fas_name][collection_name][acl.acl] = \
                acl.status

        for aclname in planned_acls:
            for user in commit_acls:
                if collection_name in commit_acls[user] and \
                        aclname not in commit_acls[user][collection_name]:
                    commit_acls[user][collection_name][aclname] = None

    # If the user is not an admin, he/she can only access his/her ACLs
    username = flask.g.fas_user.username
    if username not in admins and not is_pkgdb_admin(flask.g.fas_user):
        tmp = {username: []}
        if username in commit_acls:
            tmp = {username: commit_acls[username]}
        commit_acls = tmp

    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        sub_acls = flask.request.values.getlist('acls')
        sub_users = flask.request.values.getlist('user')
        sub_branches = flask.request.values.getlist('branch')
        changed = False

        if sub_acls and len(sub_acls) == (len(sub_users) * len(sub_branches)):
            cnt = 0
            for cnt_u in range(len(sub_users)):
                for cnt_b in range(len(sub_branches)):
                    lcl_acl = sub_acls[cnt]
                    lcl_user = sub_users[cnt_u]
                    lcl_branch = sub_branches[cnt_b]

                    if lcl_acl not in acl_status:
                        flask.flash('Invalid ACL: %s' % lcl_acl, 'error')
                        cnt += 1
                        continue

                    if lcl_user not in commit_acls:
                        flask.flash('Invalid user: %s' % lcl_user, 'error')
                        cnt += 1
                        continue

                    if lcl_branch not in branches_inv or (
                        branches_inv[lcl_branch] in commit_acls[lcl_user]
                            and commit_acls[lcl_user][
                                branches_inv[lcl_branch]][
                                    update_acl] == lcl_acl):
                        cnt += 1
                        continue

                    if not lcl_acl:
                        if branches_inv[lcl_branch] \
                                not in commit_acls[lcl_user]:
                            cnt += 1
                            continue
                        elif branches_inv[lcl_branch] \
                                in commit_acls[lcl_user] \
                                and username != lcl_user:
                            flask.flash(
                                'Only the user can remove his/her ACL',
                                'error')
                            cnt += 1
                            continue

                    try:
                        pkgdblib.set_acl_package(
                            SESSION,
                            namespace=namespace,
                            pkg_name=package.name,
                            pkg_branch=lcl_branch,
                            pkg_user=lcl_user,
                            acl=update_acl,
                            status=lcl_acl,
                            user=flask.g.fas_user,
                        )
                        SESSION.commit()
                        flask.flash("%s's %s ACL updated on %s" % (
                            lcl_user, update_acl, lcl_branch))
                        changed = True
                    except PkgdbException as err:
                        SESSION.rollback()
                        flask.flash(str(err), 'error')
                    cnt += 1

            SESSION.commit()
            if not changed:
                flask.flash('Nothing to update')
            return flask.redirect(flask.url_for(
                '.package_info',
                namespace=package.namespace,
                package=package.name)
            )
        else:
            flask.flash('Invalid input submitted', 'error')

    return flask.render_template(
        'acl_update.html',
        acl=update_acl,
        acl_status=acl_status,
        package=package,
        form=form,
        branches=branches,
        commit_acls=commit_acls,
        admins=admins,
        committers=committers,
    )
Exemplo n.º 25
0
def package_info(package):
    ''' Display the information about the specified package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    package_acls = []
    branch_admin = []
    is_poc = False
    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue
        tmp = {}
        tmp['collection'] = '%s %s' % (pkg.collection.name,
                                       pkg.collection.version)
        tmp['branchname'] = pkg.collection.branchname
        tmp['point_of_contact'] = pkg.point_of_contact
        tmp['status'] = pkg.status
        if hasattr(flask.g, 'fas_user') and flask.g.fas_user and \
                pkg.point_of_contact == flask.g.fas_user.username:
            is_poc = True

        acls = {}
        for acl in pkg.acls:
            tmp2 = {'acl': acl.acl, 'status': acl.status}
            if acl.fas_name in acls:
                acls[acl.fas_name].append(tmp2)
            else:
                acls[acl.fas_name] = [tmp2]

        ## This list is a little hacky, but we would have to save ACLs
        ## in their own table otherwise.
        planned_acls = set(
            ['approveacls', 'commit', 'watchbugzilla', 'watchcommits'])

        for fas_name in acls:
            seen_acls = set([acl['acl'] for acl in acls[fas_name]])
            for aclname in planned_acls - seen_acls:
                acls[fas_name].append({'acl': aclname, 'status': ''})
        tmp['acls'] = acls

        package_acls.append(tmp)
        if is_pkg_admin(SESSION, flask.g.fas_user, package.name,
                        pkg.collection.branchname):
            branch_admin.append(pkg.collection.branchname)

    package_acls.reverse()
    if package_acls:
        package_acls.insert(0, package_acls.pop())

    return flask.render_template(
        'package.html',
        package=package,
        package_acl=package_acls,
        branch_admin=branch_admin,
        is_poc=is_poc,
    )
Exemplo n.º 26
0
def package_unretire(namespace, package, full=True):
    ''' Asks an admin to unretire the package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    # Get the list of retired branches
    retire_collections = [
        acl.collection.branchname for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Retired'
    ]

    # Get the list of all the collections active or under development
    collections = [
        collection.branchname for collection in pkgdb2.lib.search_collection(
            SESSION, '*', 'Under Development')
        if collection.branchname in retire_collections
    ]
    collections.reverse()
    active_collections = pkgdb2.lib.search_collection(SESSION, '*', 'Active')
    active_collections.reverse()
    cnt = 0
    # Restrict the Fedora branch to 2 active versions
    for collection in active_collections:
        if collection.name.lower() == 'fedora':
            if cnt >= 2:
                continue
            cnt += 1
        if collection.branchname not in retire_collections:
            continue
        collections.append(collection.branchname)

    form = pkgdb2.forms.UnretireForm(collections=collections)

    if form.validate_on_submit():
        review_url = form.review_url.data
        review_url = review_url.strip() if review_url else None
        checks_ok = True
        for br in form.branches.data:
            if br == 'master' and not review_url:
                checks_ok = False
                flask.flash(
                    'You must provide a review URL to un-retire master',
                    'error')
                break
            elif br.startswith(
                    'e') and 'master' in collections and not review_url:
                checks_ok = False
                flask.flash(
                    'You must provide a review URL to un-retire an EPEL '
                    'branch if master is also retired', 'error')
                break

        if not checks_ok:
            return flask.redirect(
                flask.url_for('.package_info',
                              namespace=package.namespace,
                              package=package.name))

        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.add_unretire_request(
                            session=SESSION,
                            namespace=namespace,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            review_url=form.review_url.data,
                            user=flask.g.fas_user,
                        )
                        flask.flash(
                            'Admins have been asked to un-retire branch: %s' %
                            acl.collection.branchname)
                    except pkgdblib.PkgdbException, err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                    except SQLAlchemyError, err:
                        SESSION.rollback()
                        flask.flash(
                            'Could not save the request for branch: %s, has '
                            'it already been requested?' %
                            acl.collection.branchname, 'error')
                else:  # pragma: no cover
                    flask.flash('This package is not orphaned on branch: %s' %
                                acl.collection.branchname)
Exemplo n.º 27
0
def package_give(package, full=True):
    ''' Gives the PoC of a package to someone else. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    # Restrict the branch to the one current user is PoC of (unless admin
    # or group)
    collect_name = []
    for acl in package_acl:
        if acl.point_of_contact != flask.g.fas_user.username and \
                not is_pkgdb_admin(flask.g.fas_user) and \
                not acl.point_of_contact.startswith('group::'):
            pass
        else:
            if acl.point_of_contact.startswith('group::'):
                group = acl.point_of_contact.split('group::')[0]
                if group not in flask.g.fas_user.groups:
                    pass
            elif acl.collection.status != 'EOL':
                collect_name.append(acl.collection.branchname)

    form = pkgdb2.forms.GivePoCForm(collections=collect_name)

    acls = ['commit', 'watchbugzilla', 'watchcommits', 'approveacls']

    if form.validate_on_submit():
        collections = form.branches.data
        pkg_poc = form.poc.data
        if pkg_poc.startswith('group::'):
            acls = ['commit', 'watchbugzilla', 'watchcommits']

        try:
            for pkg_collection in collections:
                message = pkgdblib.update_pkg_poc(
                    SESSION,
                    pkg_name=packagename,
                    pkg_branch=pkg_collection,
                    pkg_poc=pkg_poc,
                    user=flask.g.fas_user,
                )
                flask.flash(message)

                for acl in acls:
                    pkgdblib.set_acl_package(SESSION,
                                             pkg_name=packagename,
                                             pkg_branch=pkg_collection,
                                             pkg_user=pkg_poc,
                                             acl=acl,
                                             status='Approved',
                                             user=flask.g.fas_user)

                SESSION.commit()
        except pkgdblib.PkgdbBugzillaException, err:  # pragma: no cover
            APP.logger.exception(err)
            flask.flash(str(err), 'error')
            SESSION.rollback()
        except pkgdblib.PkgdbException, err:
            SESSION.rollback()
            flask.flash(str(err), 'error')
Exemplo n.º 28
0
def package_retire(namespace, package, full=True):
    ''' Gives the possibility to orphan or take a package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    if not is_pkgdb_admin(flask.g.fas_user):
        flask.flash(
            'Only Admins are allowed to retire package here, '
            'you should use `fedpkg retire`.', 'errors')
        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    collections = [
        acl.collection.branchname
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Orphaned'
    ]

    form = pkgdb2.forms.BranchForm(collections=collections)

    if form.validate_on_submit():
        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.update_pkg_status(
                            session=SESSION,
                            namespace=namespace,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            status='Retired',
                            user=flask.g.fas_user
                        )
                        flask.flash(
                            'This package has been retired on branch: %s'
                            % acl.collection.branchname)
                    except PkgdbException as err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                        APP.logger.exception(err)
                else:  # pragma: no cover
                    flask.flash(
                        'This package has not been orphaned on '
                        'branch: %s' % acl.collection.branchname)

        try:
            SESSION.commit()
        # Keep it in, but normally we shouldn't hit this
        except PkgdbException as err:  # pragma: no cover
            # We should never hit this
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash(str(err), 'error')

        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    return flask.render_template(
        'branch_selection.html',
        full=full,
        package=package,
        form=form,
        action='retire',
    )
Exemplo n.º 29
0
def package_request_branch(namespace, package, full=True):
    ''' Gives the possibility to request a new branch for this package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(SESSION, namespace, package,
                                          limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    branches = [
        pkg.collection.branchname for pkg in package_acl
        if pkg.collection.status != 'EOL'
    ]

    collections = pkgdb2.lib.search_collection(SESSION, '*',
                                               'Under Development')
    collections.extend(pkgdb2.lib.search_collection(SESSION, '*', 'Active'))

    # List the possible branches that this package does not already have.
    branches_possible = [
        collec.branchname for collec in collections
        if collec.branchname not in branches
    ]

    # Further limit that list to only the branches allowed for this namespace.
    namespace_policy = APP.config.get('PKGDB2_NAMESPACE_POLICY')
    policy = namespace_policy.get(pkg.package.namespace)
    if policy:
        branches_possible = [b for b in branches_possible if b in policy]

    form = pkgdb2.forms.BranchForm(collections=branches_possible)

    if form.validate_on_submit():
        for branch in form.branches.data:
            try:
                msg = pkgdblib.add_new_branch_request(
                    session=SESSION,
                    namespace=package.namespace,
                    pkg_name=package.name,
                    clt_to=branch,
                    user=flask.g.fas_user)
                SESSION.commit()
                flask.flash(msg)
            except PkgdbException as err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()
            except SQLAlchemyError as err:  # pragma: no cover
                APP.logger.exception(err)
                flask.flash(
                    'Could not save the request to the database for '
                    'branch: %s' % branch, 'error')
                SESSION.rollback()

        return flask.redirect(
            flask.url_for('.package_info',
                          namespace=package.namespace,
                          package=package.name))

    return flask.render_template(
        'request_branch.html',
        full=full,
        package=package,
        form=form,
        action='request_branch',
    )
Exemplo n.º 30
0
def package_unretire(namespace, package, full=True):
    ''' Asks an admin to unretire the package. '''

    if not bool(full) or str(full) in ['0', 'False']:
        full = False

    try:
        package_acl = pkgdblib.get_acl_package(
            SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    # Get the list of retired branches
    retire_collections = [
        acl.collection.branchname
        for acl in package_acl
        if acl.collection.status in ['Active', 'Under Development']
        and acl.status == 'Retired'
    ]

    # Get the list of all the collections active or under development
    collections = [
        collection.branchname for collection in
        pkgdb2.lib.search_collection(SESSION, '*', 'Under Development')
        if collection.branchname in retire_collections
    ]
    collections.reverse()
    active_collections = pkgdb2.lib.search_collection(SESSION, '*', 'Active')
    active_collections.reverse()
    cnt = 0
    # Restrict the Fedora branch to 2 active versions
    for collection in active_collections:
        if collection.name.lower() == 'fedora':
                if cnt >= 2:
                    continue
                cnt += 1
        if collection.branchname not in retire_collections:
            continue
        collections.append(collection.branchname)

    form = pkgdb2.forms.UnretireForm(collections=collections)

    if form.validate_on_submit():
        review_url = form.review_url.data
        review_url = review_url.strip() if review_url else None

        checks_ok = True

        # Check the review URL
        bz = APP.config.get('PKGDB2_BUGZILLA_URL')
        review_url = pkgdblib.check_bz_url(bz, review_url)

        for br in form.branches.data:
            if br.startswith('e') \
                    and 'master' in collections \
                    and not review_url:
                checks_ok = False
                flask.flash(
                    'You must provide a valid review URL to un-retire an '
                    'EPEL branch if master is also retired', 'error')
                break

        if not checks_ok:
            return flask.redirect(flask.url_for(
                '.package_info',
                namespace=package.namespace,
                package=package.name)
            )

        for acl in package_acl:
            if acl.collection.branchname in form.branches.data:
                if acl.point_of_contact == 'orphan':
                    try:
                        pkgdblib.add_unretire_request(
                            session=SESSION,
                            namespace=namespace,
                            pkg_name=package.name,
                            pkg_branch=acl.collection.branchname,
                            review_url=review_url,
                            user=flask.g.fas_user,
                        )
                        flask.flash(
                            'Admins have been asked to un-retire branch: %s'
                            % acl.collection.branchname)
                    except PkgdbException as err:  # pragma: no cover
                        # We should never hit this
                        flask.flash(str(err), 'error')
                        SESSION.rollback()
                    except SQLAlchemyError as err:
                        APP.logger.exception(err)
                        SESSION.rollback()
                        flask.flash(
                            'Could not save the request for branch: %s, has '
                            'it already been requested?'
                            % acl.collection.branchname, 'error')
                else:  # pragma: no cover
                    flask.flash(
                        'This package is not orphaned on branch: %s'
                        % acl.collection.branchname)

        try:
            SESSION.commit()
        # Keep it in, but normally we shouldn't hit this
        except PkgdbException as err:  # pragma: no cover
            # We should never hit this
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash(str(err), 'error')

        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    return flask.render_template(
        'request_unretire.html',
        full=full,
        package=package,
        form=form,
        action='unretire',
    )
Exemplo n.º 31
0
def update_acl(package, update_acl):
    ''' Update the acls of a package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    statues = pkgdblib.get_status(SESSION)
    planned_acls = set(statues['pkg_acl'])
    acl_status = list(set(statues['acl_status']))
    acl_status.insert(0, '')

    if update_acl not in planned_acls:
        flask.flash('Invalid ACL to update.', 'errors')
        return flask.redirect(
            flask.url_for('.package_info', package=package.name))

    branches = {}
    branches_inv = {}
    commit_acls = {}
    admins = {}
    committers = []

    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue

        collection_name = '%s %s' % (pkg.collection.name,
                                     pkg.collection.version)

        if collection_name not in branches:
            branches[collection_name] = pkg.collection.branchname

        if pkg.collection.branchname not in branches_inv:
            branches_inv[pkg.collection.branchname] = collection_name

        for acl in pkg.acls:

            if acl.acl == 'approveacls' and acl.status == 'Approved':
                if acl.fas_name not in admins:
                    admins[acl.fas_name] = set()
                admins[acl.fas_name].add(collection_name)

            if acl.acl != update_acl:
                continue

            committers.append(acl.fas_name)
            if acl.fas_name not in commit_acls:
                commit_acls[acl.fas_name] = {}
            if collection_name not in commit_acls[acl.fas_name]:
                commit_acls[acl.fas_name][collection_name] = {}

            commit_acls[acl.fas_name][collection_name][acl.acl] = \
                acl.status

        for aclname in planned_acls:
            for user in commit_acls:
                if collection_name in commit_acls[user] and \
                        aclname not in commit_acls[user][collection_name]:
                    commit_acls[user][collection_name][aclname] = None

    # If the user is not an admin, he/she can only access his/her ACLs
    username = flask.g.fas_user.username
    if username not in admins and not is_pkgdb_admin(flask.g.fas_user):
        tmp = {username: []}
        if username in commit_acls:
            tmp = {username: commit_acls[username]}
        commit_acls = tmp

    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        sub_acls = flask.request.values.getlist('acls')
        sub_users = flask.request.values.getlist('user')
        sub_branches = flask.request.values.getlist('branch')
        changed = False

        if sub_acls and len(sub_acls) == (len(sub_users) * len(sub_branches)):
            cnt = 0
            for cnt_u in range(len(sub_users)):
                for cnt_b in range(len(sub_branches)):
                    lcl_acl = sub_acls[cnt]
                    lcl_user = sub_users[cnt_u]
                    lcl_branch = sub_branches[cnt_b]

                    if lcl_acl not in acl_status:
                        flask.flash('Invalid ACL: %s' % lcl_acl, 'error')
                        cnt += 1
                        continue

                    if lcl_user not in commit_acls:
                        flask.flash('Invalid user: %s' % lcl_user, 'error')
                        cnt += 1
                        continue

                    if lcl_branch not in branches_inv or (
                            branches_inv[lcl_branch] in commit_acls[lcl_user]
                            and commit_acls[lcl_user][branches_inv[lcl_branch]]
                        [update_acl] == lcl_acl):
                        cnt += 1
                        continue

                    if not lcl_acl:
                        if branches_inv[lcl_branch] \
                                not in commit_acls[lcl_user]:
                            cnt += 1
                            continue
                        elif branches_inv[lcl_branch] \
                                in commit_acls[lcl_user] \
                                and username != lcl_user:
                            flask.flash('Only the user can remove his/her ACL',
                                        'error')
                            cnt += 1
                            continue

                    try:
                        pkgdblib.set_acl_package(
                            SESSION,
                            pkg_name=package.name,
                            pkg_branch=lcl_branch,
                            pkg_user=lcl_user,
                            acl=update_acl,
                            status=lcl_acl,
                            user=flask.g.fas_user,
                        )
                        SESSION.commit()
                        flask.flash("%s's %s ACL updated on %s" %
                                    (lcl_user, update_acl, lcl_branch))
                        changed = True
                    except pkgdblib.PkgdbException, err:
                        SESSION.rollback()
                        flask.flash(str(err), 'error')
                    cnt += 1

            SESSION.commit()
            if not changed:
                flask.flash('Nothing to update')
            return flask.redirect(
                flask.url_for('.package_info', package=package.name))
        else:
            flask.flash('Invalid input submitted', 'error')
Exemplo n.º 32
0
def api_branch_request(package, namespace='rpms'):
    '''
    New branch request
    ------------------
    Request a new branch for package in pkgdb.

    ::

        /api/request/branch/<namespace>/<package>

    Accepts POST queries only.

    :arg package: The name of the package
    :arg branches: The list of branches desired for this package.
    :arg namespace: The namespace of the package
        (default to ``rpms``).


    Sample response:

    ::

        {
          'messages': [
            'Branch f17 created for user pingou',
          ],
          'output': 'ok'
        }

        {
          "messages": [
            "Branch el6 requested for user pingou"
          ],
          "output": "ok"
        }

        {
          "output": "notok",
          'error': 'User "pingou" is not in the packager group',
        }

        {
          "error": "Invalid input submitted",
          "error_detail": [
            "branches: 'foobar' is not a valid choice for this field",
          ],
          "output": "notok"
        }

    '''
    httpcode = 200
    output = {}
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, namespace, package)
        package = pkgdblib.search_package(
            SESSION, namespace, package, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        output['output'] = 'notok'
        output['error'] = 'No package found: %s/%s' % (namespace, package)
        httpcode = 404
    else:

        branches = [
            pkg.collection.branchname
            for pkg in package_acl
            if pkg.collection.status != 'EOL'
        ]

        collections = pkgdblib.search_collection(
            SESSION, '*', 'Under Development')
        collections.extend(pkgdblib.search_collection(
            SESSION, '*', 'Active'))
        branches_possible = [
            collec.branchname
            for collec in collections
            if collec.branchname not in branches]

        form = forms.BranchForm(
            collections=branches_possible,
            csrf_enabled=False,
        )

        if form.validate_on_submit():
            try:
                messages = []
                for branch in form.branches.data:
                    msg = pkgdblib.add_new_branch_request(
                        session=SESSION,
                        namespace=namespace,
                        pkg_name=package.name,
                        clt_to=branch,
                        user=flask.g.fas_user)
                    if msg:
                        messages.append(msg)
                SESSION.commit()
                output['output'] = 'ok'
                output['messages'] = messages
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                SESSION.rollback()
                output['output'] = 'notok'
                output['error'] = str(err)
                httpcode = 400
            except SQLAlchemyError, err:  # pragma: no cover
                SESSION.rollback()
                APP.logger.exception(err)
                output['output'] = 'notok'
                output['error'] = 'Could not save the request to the '\
                    'database for branch: %s' % branch
                httpcode = 400
Exemplo n.º 33
0
def api_package_info(pkgname=None):
    '''
Package information
-------------------
    Return information about a specific package.

    ::

        /api/package/<pkg_name>/

        /api/package/?pkgname=<pkg_name>

    Accept GET queries only

    :arg pkgname: The name of the package to retrieve the information of.
    :kwarg branches: Restricts the package information to one or more
        collection (branches).
    :kwarg eol: a boolean to specify whether to include results for
        EOL collections or not. Defaults to False.
        If True, it will return results for all collections (including EOL).
        If False, it will return results only for non-EOL collections.
    :kwarg acls: a boolean to specify whether to include the ACLs in the
        results. Defaults to True.
        If True, it will include the ACL of the package in the collection.
        If False, it will not include the ACL of the package in the
        collection.

    Sample response:

    ::

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "point_of_contact": "pingou",
              "critpath": False,
              "package": {
                "status": "Approved",
                "upstream_url": null,
                "description": "Guake is a drop-down terminal for Gnome "
                             "Desktop Environment, so you just need to "
                             "press a key to invoke him,and press again "
                             "to hide."
                "summary": "Drop-down terminal for GNOME",
                "creation_date": 1385365548.0,
                "review_url": null,
                "name": "guake"
              },
              "collection": {
                "status": "Under Development",
                "branchname": "master",
                "version": "devel",
                "name": "Fedora"
              },
              "acls": [
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchcommits"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "watchbugzilla"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "commit"
                },
                {
                  "status": "Approved",
                  "fas_name": "pingou",
                  "acl": "approveacls"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchcommits"
                },
                {
                  "status": "Obsolete",
                  "fas_name": "maxamillion",
                  "acl": "watchbugzilla"
                },
                {
                  "acl": "commit",
                  "fas_name": "group::provenpackager",
                  "status": "Approved"
                }
              ],
              "status_change": 1385366044.0
            },
            ...
          ]
        }

    '''
    httpcode = 200
    output = {}

    pkg_name = flask.request.args.get('pkgname', pkgname)
    branches = flask.request.args.getlist('branches', None)
    eol = flask.request.args.get('eol', False)
    acls = flask.request.args.get('acls', True)
    if str(acls).lower() in ['0', 'false']:
        acls = False

    try:
        packages = pkgdblib.get_acl_package(
            SESSION,
            pkg_name=pkg_name,
            pkg_clt=branches,
            eol=eol,
        )
        if not packages:
            output['output'] = 'notok'
            output['error'] = 'No package found on these branches: %s' \
                % ', '.join(branches)
            httpcode = 404
        else:
            output['output'] = 'ok'
            output['packages'] = [
                pkg.to_json(not_provenpackager=APP.config.get(
                    'PKGS_NOT_PROVENPACKAGER'), acls=acls)
                for pkg in packages]
    except NoResultFound:
        output['output'] = 'notok'
        output['error'] = 'Package: %s not found' % pkg_name
        httpcode = 404

    jsonout = flask.jsonify(output)
    jsonout.status_code = httpcode
    return jsonout
Exemplo n.º 34
0
def package_info(package):
    ''' Display the information about the specified package. '''

    packagename = package
    package = None
    try:
        package_acl = pkgdblib.get_acl_package(SESSION, packagename)
        package = pkgdblib.search_package(SESSION, packagename, limit=1)[0]
    except (NoResultFound, IndexError):
        SESSION.rollback()
        flask.flash('No package of this name found.', 'errors')
        return flask.render_template('msg.html')

    package_acls = []
    branch_admin = []
    is_poc = False
    for pkg in package_acl:
        if pkg.collection.status == 'EOL':  # pragma: no cover
            continue
        tmp = {}
        tmp['collection'] = '%s %s' % (pkg.collection.name,
                                       pkg.collection.version)
        tmp['branchname'] = pkg.collection.branchname
        tmp['point_of_contact'] = pkg.point_of_contact
        tmp['status'] = pkg.status
        if hasattr(flask.g, 'fas_user') and flask.g.fas_user and \
                pkg.point_of_contact == flask.g.fas_user.username:
            is_poc = True

        acls = {}
        for acl in pkg.acls:
            tmp2 = {'acl': acl.acl, 'status': acl.status}
            if acl.fas_name in acls:
                acls[acl.fas_name].append(tmp2)
            else:
                acls[acl.fas_name] = [tmp2]

        ## This list is a little hacky, but we would have to save ACLs
        ## in their own table otherwise.
        planned_acls = set(['approveacls', 'commit', 'watchbugzilla',
                            'watchcommits'])

        for fas_name in acls:
            seen_acls = set([acl['acl'] for acl in acls[fas_name]])
            for aclname in planned_acls - seen_acls:
                acls[fas_name].append({'acl': aclname, 'status': ''})
        tmp['acls'] = acls

        package_acls.append(tmp)
        if is_pkg_admin(SESSION, flask.g.fas_user, package.name,
                        pkg.collection.branchname):
            branch_admin.append(pkg.collection.branchname)

    package_acls.reverse()
    if package_acls:
        package_acls.insert(0, package_acls.pop())

    return flask.render_template(
        'package.html',
        package=package,
        package_acl=package_acls,
        branch_admin=branch_admin,
        is_poc=is_poc,
    )