예제 #1
0
def list_packages(motif=None, orphaned=False, status='Approved',
                  origin='list_packages'):
    ''' Display the list of packages corresponding to the motif. '''

    pattern = flask.request.args.get('motif', motif) or '*'
    branches = flask.request.args.get('branches', None)
    owner = flask.request.args.get('owner', None)
    orphaned = bool(flask.request.args.get('orphaned', orphaned))
    status = flask.request.args.get('status', status)
    limit = flask.request.args.get('limit', APP.config['ITEMS_PER_PAGE'])
    page = flask.request.args.get('page', 1)

    try:
        page = int(page)
    except ValueError:
        page = 1

    try:
        int(limit)
    except ValueError:
        limit = APP.config['ITEMS_PER_PAGE']
        flask.flash('Incorrect limit provided, using default', 'errors')

    packages = pkgdblib.search_package(
        SESSION,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
    )
    packages_count = pkgdblib.search_package(
        SESSION,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
        count=True
    )
    total_page = int(ceil(packages_count / float(limit)))

    return flask.render_template(
        'list_packages.html',
        origin=origin,
        packages=packages,
        motif=motif,
        total_page=total_page,
        packages_count=packages_count,
        page=page
    )
예제 #2
0
def list_packages(motif=None,
                  orphaned=False,
                  status='Approved',
                  origin='list_packages'):
    ''' Display the list of packages corresponding to the motif. '''

    pattern = flask.request.args.get('motif', motif) or '*'
    branches = flask.request.args.get('branches', None)
    owner = flask.request.args.get('owner', None)
    orphaned = bool(flask.request.args.get('orphaned', orphaned))
    status = flask.request.args.get('status', status)
    limit = flask.request.args.get('limit', APP.config['ITEMS_PER_PAGE'])
    page = flask.request.args.get('page', 1)

    try:
        page = int(page)
    except ValueError:
        page = 1

    try:
        int(limit)
    except ValueError:
        limit = APP.config['ITEMS_PER_PAGE']
        flask.flash('Incorrect limit provided, using default', 'errors')

    packages = pkgdblib.search_package(
        SESSION,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
    )
    packages_count = pkgdblib.search_package(SESSION,
                                             pkg_name=pattern,
                                             pkg_branch=branches,
                                             pkg_poc=owner,
                                             orphaned=orphaned,
                                             status=status,
                                             page=page,
                                             limit=limit,
                                             count=True)
    total_page = int(ceil(packages_count / float(limit)))

    return flask.render_template('list_packages.html',
                                 origin=origin,
                                 packages=packages,
                                 motif=motif,
                                 total_page=total_page,
                                 packages_count=packages_count,
                                 page=page)
예제 #3
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)
예제 #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
예제 #5
0
파일: packages.py 프로젝트: cverna/pkgdb2
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()
예제 #6
0
파일: packages.py 프로젝트: cverna/pkgdb2
def package_anitya(namespace, package, full=True):
    """ Return information anitya integration about this package.
    """
    if str(full).lower() in ['0', 'false']:
        full = False

    pkg = None
    try:
        pkg = 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')

    url = '%s/api/project/%s/%s' % (
        APP.config['PKGDB2_ANITYA_URL'],
        APP.config['PKGDB2_ANITYA_DISTRO'],
        package
    )

    data = {}
    try:
        req = requests.get(url)
        if req.status_code != 200:
            raise pkgdblib.PkgdbException(
                'Querying anitya returned a status %s' % req.status_code)
        else:
            data = req.json()
    except Exception, err:
        flask.flash(err.message, 'error')
        pass
예제 #7
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
예제 #8
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)
예제 #9
0
def package_anitya(package, full=True):
    """ Return information anitya integration about this package.
    """
    if str(full).lower() in ['0', 'false']:
        full = False

    pkg = None
    try:
        pkg = 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')

    url = '%s/api/project/%s/%s' % (APP.config['PKGDB2_ANITYA_URL'],
                                    APP.config['PKGDB2_ANITYA_DISTRO'],
                                    package)

    data = {}
    try:
        req = requests.get(url)
        if req.status_code != 200:
            raise pkgdblib.PkgdbException(
                'Querying anitya returned a status %s' % req.status_code)
        else:
            data = req.json()
    except Exception, err:
        flask.flash(err.message, 'error')
        pass
예제 #10
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')
예제 #11
0
def watch_package(package):
    ''' Request watch* ACLs on a package.
    Anyone can request these ACLs, no need to be a packager.
    '''
    try:
        pkg = pkgdblib.search_package(SESSION, pkg_name=package, limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(flask.url_for('.package_info', package=package))

    pkg_acls = ['watchcommits', 'watchbugzilla']
    pkg_branchs = [pkglist.collection.branchname for pkglist in pkg.listings]
    try:
        for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
            pkgdblib.set_acl_package(
                SESSION,
                pkg_name=package,
                pkg_branch=collec,
                pkg_user=flask.g.fas_user.username,
                acl=acl,
                status='Approved',
                user=flask.g.fas_user,
            )
        SESSION.commit()
        flask.flash('ACLs updated')
    # Let's keep this in although we should never see it
    except pkgdblib.PkgdbException, err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(str(err), 'error')
예제 #12
0
def watch_package(package):
    ''' Request watch* ACLs on a package.
    Anyone can request these ACLs, no need to be a packager.
    '''
    try:
        pkg = pkgdblib.search_package(SESSION, pkg_name=package, limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(
            flask.url_for('.package_info', package=package))

    pkg_acls = ['watchcommits', 'watchbugzilla']
    pkg_branchs = [pkglist.collection.branchname for pkglist in pkg.listings]
    try:
        for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
            pkgdblib.set_acl_package(
                SESSION,
                pkg_name=package,
                pkg_branch=collec,
                pkg_user=flask.g.fas_user.username,
                acl=acl,
                status='Approved',
                user=flask.g.fas_user,
            )
        SESSION.commit()
        flask.flash('ACLs updated')
    # Let's keep this in although we should never see it
    except pkgdblib.PkgdbException, err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(str(err), 'error')
예제 #13
0
def package_anitya(package, full=True):
    """ Return information anitya integration about this package.
    """
    if str(full).lower() in ['0', 'false']:
        full = False

    pkg = None
    try:
        pkg = 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')

    url = '%s/api/project/%s/%s' % (
        APP.config['PKGDB2_ANITYA_URL'],
        APP.config['PKGDB2_ANITYA_DISTRO'],
        package
    )

    req = requests.get(url)
    data = req.json()

    return flask.render_template(
        'package_anitya.html',
        full=full,
        package=package,
        pkg=pkg,
        data=data,
    )
예제 #14
0
def package_give_acls(namespace, package):
    ''' Give acls to a specified user for a specific package. '''

    try:
        pkg = pkgdblib.search_package(SESSION,
                                      namespace=namespace,
                                      pkg_name=package,
                                      limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(flask.url_for('.list_packages'))

    collections = [
        pkglist.collection for pkglist in pkg.listings
        if pkglist.collection.status != 'EOL'
    ]

    acls = pkgdblib.get_status(SESSION)

    form = pkgdb2.forms.SetAclPackageForm(
        collections_obj=collections,
        pkg_acl=acls['pkg_acl'],
        acl_status=acls['acl_status'],
        namespaces=acls['namespaces'],
    )
    form.pkgname.data = package
    if str(form.namespace.data) in ['None', '']:
        form.namespace.data = 'rpms'

    if form.validate_on_submit():
        pkg_branchs = form.branches.data
        pkg_acls = form.acl.data
        pkg_user = form.user.data
        acl_status = form.acl_status.data

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'

                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=pkg_user,
                    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=namespace,
                              package=package))
        except pkgdblib.PkgdbException, err:
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #15
0
파일: acls.py 프로젝트: cverna/pkgdb2
def giveup_acl(namespace, package, acl):
    ''' Request acls for a specific package. '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']
        if acl not in pkg_acl:
            flask.flash('Invalid ACL provided %s.' % acl, 'errors')
            return flask.render_template('msg.html')

        try:
            pkg = pkgdblib.search_package(
                SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(flask.url_for(
                '.package_info', namespace=namespace, package=package))

        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in
            ['Active', 'Under Development'] and flask.g.fas_user.username in
            [tmpacl.fas_name for tmpacl in pkglist.acls]
        ])

        if not pkg_branchs:
            flask.flash(
                'No active branches found for you for the ACL: %s' % acl,
                'error')
            return flask.redirect(flask.url_for(
                '.package_info', namespace=namespace, package=package))

        for branch in pkg_branchs:
            print package, namespace, branch, acl, flask.g.fas_user.username
            try:
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=branch,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
                flask.flash(
                    'Your ACL %s is obsoleted on branch %s of package %s'
                    % (acl, branch, package))
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                flask.flash(str(err), 'error')
                SESSION.rollback()

        try:
            SESSION.commit()
        # Keep it in, but normally we shouldn't hit this
        except pkgdblib.PkgdbException, err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #16
0
def comaintain_package(package):
    ''' Asks for ACLs to co-maintain a package.
    You need to be a packager to request co-maintainership.
    '''
    # This is really wearing belt and suspenders, the decorator above
    # should take care of this
    if not 'packager' in flask.g.fas_user.groups:  # pragma: no cover
        flask.flash(
            'You must be a packager to apply to be a comaintainer',
            'errors')
        return flask.redirect(flask.url_for(
            '.package_info', package=package))

    try:
        pkg = pkgdblib.search_package(SESSION, pkg_name=package, limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(
            flask.url_for('.package_info', package=package))

    pkg_acls = ['commit', 'watchcommits', 'watchbugzilla']
    pkg_branchs = [pkglist.collection.branchname for pkglist in pkg.listings]

    # Make sure the requester does not already have commit
    pkg_branchs2 = []
    for pkg_branch in pkg_branchs:
        if pkgdblib.has_acls(SESSION, flask.g.fas_user.username, pkg.name,
                             pkg_branch, 'commit'):
            flask.flash(
                'You are already a co-maintainer on %s' % pkg_branch,
                'error')
        else:
            pkg_branchs2.append(pkg_branch)
    pkg_branchs = pkg_branchs2

    if not pkg_branchs:
        return flask.redirect(flask.url_for('.package_info', package=package))

    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'
            pkgdblib.set_acl_package(
                SESSION,
                pkg_name=package,
                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')
    # Let's keep this in although we should never see it
    except pkgdblib.PkgdbException, err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(str(err), 'error')
예제 #17
0
def delete_package(namespace, package):
    ''' Delete the specified package.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if not form.validate_on_submit():
        flask.flash('Invalid input', 'error')
        return flask.redirect(flask.url_for(
            '.package_info', namespace=namespace, package=package))

    packagename = package
    package = None
    try:
        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')

    for pkglist in package.listings:
        for acl in pkglist.acls:
            pkgdb2.lib.utils.log(SESSION, None, 'acl.delete', dict(
                agent=flask.g.fas_user.username,
                acl=acl.to_json(),
            ))
            SESSION.delete(acl)
        pkgdb2.lib.utils.log(SESSION, None, 'package.branch.delete', dict(
            agent=flask.g.fas_user.username,
            package_listing=pkglist.to_json(),
        ))
        SESSION.delete(pkglist)

    pkgdb2.lib.utils.log(SESSION, None, 'package.delete', dict(
        agent=flask.g.fas_user.username,
        package=package.to_json(),
    ))
    SESSION.delete(package)

    try:
        SESSION.commit()
        flask.flash('Package %s deleted' % packagename)
    except SQLAlchemyError as err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(
            'An error occured while trying to delete the package %s'
            % packagename, 'error')
        APP.logger.debug('Could not delete package: %s', packagename)
        APP.logger.exception(err)
        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=package.namespace,
            package=package.name)
        )

    return flask.redirect(
        flask.url_for('.list_packages'))
예제 #18
0
파일: acls.py 프로젝트: cydrobolt/pkgdb2
def giveup_acl(package, acl):
    ''' Request acls for a specific package. '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']
        if acl not in pkg_acl:
            flask.flash('Invalid ACL provided %s.' % acl, 'errors')
            return flask.render_template('msg.html')

        try:
            pkg = pkgdblib.search_package(
                SESSION, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info', package=package))

        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in
            ['Active', 'Under Development'] and flask.g.fas_user.username in
            [tmpacl.fas_name for tmpacl in pkglist.acls]
        ])

        if not pkg_branchs:
            flask.flash(
                'No active branches found for you for the ACL: %s' % acl,
                'error')
            return flask.redirect(
                flask.url_for('.package_info', package=package))

        for branch in pkg_branchs:
            try:
                pkgdblib.set_acl_package(
                    SESSION,
                    pkg_name=package,
                    pkg_branch=branch,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
                flask.flash(
                    'Your ACL %s is obsoleted on branch %s of package %s'
                    % (acl, branch, package))
            except pkgdblib.PkgdbException, err:
                flask.flash(str(err), 'error')
                SESSION.rollback()

        try:
            SESSION.commit()
        # Keep it in, but normally we shouldn't hit this
        except pkgdblib.PkgdbException, err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #19
0
파일: packages.py 프로젝트: cverna/pkgdb2
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()
예제 #20
0
파일: acls.py 프로젝트: cverna/pkgdb2
def package_give_acls(namespace, package):
    ''' Give acls to a specified user for a specific package. '''

    try:
        pkg = pkgdblib.search_package(
            SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(
            flask.url_for('.list_packages'))

    collections = [
        pkglist.collection
        for pkglist in pkg.listings
        if pkglist.collection.status != 'EOL']

    acls = pkgdblib.get_status(SESSION)

    form = pkgdb2.forms.SetAclPackageForm(
        collections_obj=collections,
        pkg_acl=acls['pkg_acl'],
        acl_status=acls['acl_status'],
        namespaces=acls['namespaces'],
    )
    form.pkgname.data = package
    if str(form.namespace.data) in ['None', '']:
        form.namespace.data = 'rpms'

    if form.validate_on_submit():
        pkg_branchs = form.branches.data
        pkg_acls = form.acl.data
        pkg_user = form.user.data
        acl_status = form.acl_status.data

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'

                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=pkg_user,
                    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=namespace, package=package))
        except pkgdblib.PkgdbException, err:
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #21
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')
예제 #22
0
def delete_package(package):
    ''' Delete the specified package.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if not form.validate_on_submit():
        flask.flash('Invalid input', 'error')
        return flask.redirect(flask.url_for('.package_info', package=package))

    packagename = package
    package = None
    try:
        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 pkglist in package.listings:
        for acl in pkglist.acls:
            pkgdb2.lib.utils.log(
                SESSION, None, 'acl.delete',
                dict(
                    agent=flask.g.fas_user.username,
                    acl=acl.to_json(),
                ))
            SESSION.delete(acl)
        pkgdb2.lib.utils.log(
            SESSION, None, 'package.branch.delete',
            dict(
                agent=flask.g.fas_user.username,
                package_listing=pkglist.to_json(),
            ))
        SESSION.delete(pkglist)

    pkgdb2.lib.utils.log(
        SESSION, None, 'package.delete',
        dict(
            agent=flask.g.fas_user.username,
            package=package.to_json(),
        ))
    SESSION.delete(package)

    try:
        SESSION.commit()
        flask.flash('Package %s deleted' % packagename)
    except SQLAlchemyError, err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(
            'An error occured while trying to delete the package %s' %
            packagename, 'error')
        APP.logger.debug('Could not delete package: %s', packagename)
        APP.logger.exception(err)
        return flask.redirect(
            flask.url_for('.package_info', package=package.name))
예제 #23
0
파일: acls.py 프로젝트: trasher/pkgdb2
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')
예제 #24
0
파일: acls.py 프로젝트: fedora-infra/pkgdb2
def request_acl_all_branch(namespace, package, acl):
    ''' Request the specified ACL on all branches of the specified package.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']
        if acl not in pkg_acl:
            flask.flash('Invalid ACL provided %s.' % acl, 'errors')
            return flask.render_template('msg.html')

        try:
            pkg = pkgdblib.search_package(
                SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.render_template('msg.html')

        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
                and pkglist.status == 'Approved'
        ])

        for branch in pkg_branchs:
            acl_status = 'Awaiting Review'
            pkger_grp = APP.config.get('PKGER_GROUP', 'packager')
            if acl in APP.config['AUTO_APPROVE']:
                acl_status = 'Approved'
            elif pkger_grp not in flask.g.fas_user.groups:
                flask.flash(
                    'You must be a %s to apply to the ACL: %s on %s' % (
                        pkger_grp, acl, package), 'error')

            try:
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=branch,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
                flask.flash(
                    'ACL %s requested on branch %s' % (acl, branch))
                SESSION.commit()
            except PkgdbException as err:
                SESSION.rollback()
                flask.flash(str(err), 'error')

    return flask.redirect(flask.url_for(
        '.package_info', namespace=namespace, package=package))
예제 #25
0
파일: acls.py 프로젝트: voxik/pkgdb2
def request_acl_all_branch(namespace, package, acl):
    ''' Request the specified ACL on all branches of the specified package.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        pkg_acl = pkgdblib.get_status(SESSION, 'pkg_acl')['pkg_acl']
        if acl not in pkg_acl:
            flask.flash('Invalid ACL provided %s.' % acl, 'errors')
            return flask.render_template('msg.html')

        try:
            pkg = pkgdblib.search_package(SESSION,
                                          namespace=namespace,
                                          pkg_name=package,
                                          limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.render_template('msg.html')

        pkg_branchs = set([
            pkglist.collection.branchname for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
            and pkglist.status == 'Approved'
        ])

        for branch in pkg_branchs:
            acl_status = 'Awaiting Review'
            pkger_grp = APP.config.get('PKGER_GROUP', 'packager')
            if acl in APP.config['AUTO_APPROVE']:
                acl_status = 'Approved'
            elif pkger_grp not in flask.g.fas_user.groups:
                flask.flash(
                    'You must be a %s to apply to the ACL: %s on %s' %
                    (pkger_grp, acl, package), 'error')

            try:
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=branch,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
                flask.flash('ACL %s requested on branch %s' % (acl, branch))
                SESSION.commit()
            except PkgdbException as err:
                SESSION.rollback()
                flask.flash(str(err), 'error')

    return flask.redirect(
        flask.url_for('.package_info', namespace=namespace, package=package))
예제 #26
0
def comaintain_package(package):
    ''' Asks for ACLs to co-maintain a package.
    You need to be a packager to request co-maintainership.
    '''
    # This is really wearing belt and suspenders, the decorator above
    # should take care of this
    if not 'packager' in flask.g.fas_user.groups:  # pragma: no cover
        flask.flash('You must be a packager to apply to be a comaintainer',
                    'errors')
        return flask.redirect(flask.url_for('.package_info', package=package))

    try:
        pkg = pkgdblib.search_package(SESSION, pkg_name=package, limit=1)[0]
    except IndexError:
        flask.flash('No package found by this name', 'error')
        return flask.redirect(flask.url_for('.package_info', package=package))

    pkg_acls = ['commit', 'watchcommits', 'watchbugzilla']
    pkg_branchs = [pkglist.collection.branchname for pkglist in pkg.listings]

    # Make sure the requester does not already have commit
    pkg_branchs2 = []
    for pkg_branch in pkg_branchs:
        if pkgdblib.has_acls(SESSION, flask.g.fas_user.username, pkg.name,
                             pkg_branch, 'commit'):
            flask.flash('You are already a co-maintainer on %s' % pkg_branch,
                        'error')
        else:
            pkg_branchs2.append(pkg_branch)
    pkg_branchs = pkg_branchs2

    if not pkg_branchs:
        return flask.redirect(flask.url_for('.package_info', package=package))

    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'
            pkgdblib.set_acl_package(
                SESSION,
                pkg_name=package,
                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')
    # Let's keep this in although we should never see it
    except pkgdblib.PkgdbException, err:  # pragma: no cover
        SESSION.rollback()
        flask.flash(str(err), 'error')
예제 #27
0
파일: packages.py 프로젝트: cverna/pkgdb2
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()
예제 #28
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)
예제 #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'))
    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()
예제 #30
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()
예제 #31
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)
예제 #32
0
파일: acls.py 프로젝트: voxik/pkgdb2
def dropcommit_package(namespace, package):
    ''' Obsolete commit ACLs on a package.
    This method can only be used for the user itself.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(SESSION,
                                          namespace=namespace,
                                          pkg_name=package,
                                          limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info',
                              namespace=namespace,
                              package=package))

        pkg_acls = ['commit']
        pkg_branchs = set()
        for pkglist in pkg.listings:
            if pkglist.collection.status in ['Active', 'Under Development']:
                for acl in pkglist.acls:
                    if acl.fas_name == flask.g.fas_user.username and \
                            acl.acl == 'commit' and acl.status == 'Approved':
                        pkg_branchs.add(pkglist.collection.branchname)

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(
        flask.url_for('.package_info', namespace=namespace, package=package))
예제 #33
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()
예제 #34
0
파일: acls.py 프로젝트: fedora-infra/pkgdb2
def dropcommit_package(namespace, package):
    ''' Obsolete commit ACLs on a package.
    This method can only be used for the user itself.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(
                SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(flask.url_for(
                '.package_info', namespace=namespace, package=package))

        pkg_acls = ['commit']
        pkg_branchs = set()
        for pkglist in pkg.listings:
            if pkglist.collection.status in [
                    'Active', 'Under Development']:
                for acl in pkglist.acls:
                    if acl.fas_name == flask.g.fas_user.username and \
                            acl.acl == 'commit' and acl.status == 'Approved':
                        pkg_branchs.add(pkglist.collection.branchname)

        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(flask.url_for(
        '.package_info', namespace=namespace, package=package))
예제 #35
0
파일: acls.py 프로젝트: voxik/pkgdb2
def watch_package(namespace, package):
    ''' Request watch* ACLs on a package.
    Anyone can request these ACLs, no need to be a packager.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(SESSION,
                                          namespace=namespace,
                                          pkg_name=package,
                                          limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info',
                              namespace=namespace,
                              package=package))

        pkg_acls = ['watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
            and pkglist.status == 'Approved'
        ])
        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Approved',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(
        flask.url_for('.package_info', namespace=namespace, package=package))
예제 #36
0
파일: acls.py 프로젝트: fedora-infra/pkgdb2
def watch_package(namespace, package):
    ''' Request watch* ACLs on a package.
    Anyone can request these ACLs, no need to be a packager.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(
                SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(flask.url_for(
                '.package_info', namespace=namespace, package=package))

        pkg_acls = ['watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
                and pkglist.status == 'Approved'
        ])
        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Approved',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(flask.url_for(
        '.package_info', namespace=namespace, package=package))
예제 #37
0
파일: acls.py 프로젝트: trasher/pkgdb2
def unwatch_package(package):
    ''' Obsolete watch* ACLs on a package.
    This method can only be used for the user itself.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(
                SESSION, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info', package=package))

        pkg_acls = ['watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']])
        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except pkgdblib.PkgdbException, err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #38
0
파일: acls.py 프로젝트: cydrobolt/pkgdb2
def unwatch_package(package):
    ''' Obsolete watch* ACLs on a package.
    This method can only be used for the user itself.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            pkg = pkgdblib.search_package(
                SESSION, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info', package=package))

        pkg_acls = ['watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']])
        try:
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                pkgdblib.set_acl_package(
                    SESSION,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status='Obsolete',
                    user=flask.g.fas_user,
                )
            SESSION.commit()
            flask.flash('ACLs updated')
        # Let's keep this in although we should never see it
        except pkgdblib.PkgdbException, err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
예제 #39
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')
예제 #40
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,
    )
예제 #41
0
파일: acls.py 프로젝트: fedora-infra/pkgdb2
def comaintain_package(namespace, package):
    ''' Asks for ACLs to co-maintain a package.
    You need to be a packager to request co-maintainership.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        # This is really wearing belt and suspenders, the decorator above
        # should take care of this
        pkger_grp = APP.config.get('PKGER_GROUP', 'packager')
        if pkger_grp not in flask.g.fas_user.groups:  # pragma: no cover
            flask.flash(
                'You must be a %s to apply to be a comaintainer' % pkger_grp,
                'errors')
            return flask.redirect(flask.url_for(
                '.package_info', package=package))

        try:
            pkg = pkgdblib.search_package(
                SESSION, namespace=namespace, pkg_name=package, limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(flask.url_for(
                '.package_info', namespace=namespace, package=package))

        pkg_acls = ['commit', 'watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname
            for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
                and pkglist.status == 'Approved'
        ])

        # Make sure the requester does not already have commit
        pkg_branchs2 = []
        for pkg_branch in pkg_branchs:
            if pkgdblib.has_acls(
                    SESSION, flask.g.fas_user.username, pkg.namespace,
                    pkg.name, acl='commit', branch=pkg_branch):
                flask.flash(
                    'You are already a co-maintainer on %s' % pkg_branch,
                    'error')
            else:
                pkg_branchs2.append(pkg_branch)
        pkg_branchs = pkg_branchs2

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

        try:
            msgs = []
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                acl_status = 'Awaiting Review'
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'
                msg = pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
                if msg:
                    msgs.append(msg)

            SESSION.commit()
            if msgs:
                flask.flash('ACLs updated')
            else:
                flask.flash('Nothing to update')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(flask.url_for(
        '.package_info', namespace=namespace, package=package))
예제 #42
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')
예제 #43
0
def list_packages(motif=None,
                  orphaned=None,
                  status=None,
                  origin='list_packages',
                  case_sensitive=False):
    ''' Display the list of packages corresponding to the motif. '''

    pattern = flask.request.args.get('motif', motif) or '*'
    branches = flask.request.args.get('branches', None)
    owner = flask.request.args.get('owner', None)
    orphaned = flask.request.args.get('orphaned', orphaned)
    if str(orphaned) in ['False', '0']:
        orphaned = False
    status = flask.request.args.get('status', status)
    limit = flask.request.args.get('limit', APP.config['ITEMS_PER_PAGE'])
    page = flask.request.args.get('page', 1)
    case_sensitive = flask.request.args.get('case_sensitive', False)

    try:
        page = abs(int(page))
    except ValueError:
        page = 1

    try:
        limit = abs(int(limit))
    except ValueError:
        limit = APP.config['ITEMS_PER_PAGE']
        flask.flash('Incorrect limit provided, using default', 'errors')

    packages = pkgdblib.search_package(
        SESSION,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
        case_sensitive=case_sensitive,
    )
    packages_count = pkgdblib.search_package(
        SESSION,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
        count=True,
        case_sensitive=case_sensitive,
    )
    total_page = int(ceil(packages_count / float(limit)))

    select = origin.replace('list_', '')

    if len(packages) == 1:
        flask.flash('Only one package matching, redirecting you to it')
        return flask.redirect(
            flask.url_for('.package_info', package=packages[0].name))

    return flask.render_template(
        'list_packages.html',
        origin=origin,
        select=select,
        packages=packages,
        motif=motif,
        total_page=total_page,
        packages_count=packages_count,
        page=page,
        status=status,
        owner=owner,
        branches=branches,
    )
예제 #44
0
파일: acls.py 프로젝트: voxik/pkgdb2
def comaintain_package(namespace, package):
    ''' Asks for ACLs to co-maintain a package.
    You need to be a packager to request co-maintainership.
    '''
    form = pkgdb2.forms.ConfirmationForm()

    if form.validate_on_submit():
        # This is really wearing belt and suspenders, the decorator above
        # should take care of this
        pkger_grp = APP.config.get('PKGER_GROUP', 'packager')
        if pkger_grp not in flask.g.fas_user.groups:  # pragma: no cover
            flask.flash(
                'You must be a %s to apply to be a comaintainer' % pkger_grp,
                'errors')
            return flask.redirect(
                flask.url_for('.package_info', package=package))

        try:
            pkg = pkgdblib.search_package(SESSION,
                                          namespace=namespace,
                                          pkg_name=package,
                                          limit=1)[0]
        except IndexError:
            flask.flash('No package found by this name', 'error')
            return flask.redirect(
                flask.url_for('.package_info',
                              namespace=namespace,
                              package=package))

        pkg_acls = ['commit', 'watchcommits', 'watchbugzilla']
        pkg_branchs = set([
            pkglist.collection.branchname for pkglist in pkg.listings
            if pkglist.collection.status in ['Active', 'Under Development']
            and pkglist.status == 'Approved'
        ])

        # Make sure the requester does not already have commit
        pkg_branchs2 = []
        for pkg_branch in pkg_branchs:
            if pkgdblib.has_acls(SESSION,
                                 flask.g.fas_user.username,
                                 pkg.namespace,
                                 pkg.name,
                                 acl='commit',
                                 branch=pkg_branch):
                flask.flash(
                    'You are already a co-maintainer on %s' % pkg_branch,
                    'error')
            else:
                pkg_branchs2.append(pkg_branch)
        pkg_branchs = pkg_branchs2

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

        try:
            msgs = []
            for (collec, acl) in itertools.product(pkg_branchs, pkg_acls):
                acl_status = 'Awaiting Review'
                if acl in APP.config['AUTO_APPROVE']:
                    acl_status = 'Approved'
                msg = pkgdblib.set_acl_package(
                    SESSION,
                    namespace=namespace,
                    pkg_name=package,
                    pkg_branch=collec,
                    pkg_user=flask.g.fas_user.username,
                    acl=acl,
                    status=acl_status,
                    user=flask.g.fas_user,
                )
                if msg:
                    msgs.append(msg)

            SESSION.commit()
            if msgs:
                flask.flash('ACLs updated')
            else:
                flask.flash('Nothing to update')
        # Let's keep this in although we should never see it
        except PkgdbException as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    return flask.redirect(
        flask.url_for('.package_info', namespace=namespace, package=package))
예제 #45
0
def list_packages(namespace=None, motif=None, orphaned=None, status=None,
                  origin='list_packages', case_sensitive=False):
    ''' Display the list of packages corresponding to the motif. '''

    pattern = flask.request.args.get('motif', motif) or '*'
    branches = flask.request.args.get('branches', None)
    owner = flask.request.args.get('owner', None)
    namespace = flask.request.args.get('namespace', namespace)
    orphaned = flask.request.args.get('orphaned', orphaned)
    if str(orphaned) in ['False', '0']:
        orphaned = False
    status = flask.request.args.get('status', status)
    limit = flask.request.args.get('limit', APP.config['ITEMS_PER_PAGE'])
    page = flask.request.args.get('page', 1)
    case_sensitive = flask.request.args.get('case_sensitive', False)

    try:
        page = abs(int(page))
    except ValueError:
        page = 1

    try:
        limit = abs(int(limit))
    except ValueError:
        limit = APP.config['ITEMS_PER_PAGE']
        flask.flash('Incorrect limit provided, using default', 'errors')

    packages = pkgdblib.search_package(
        SESSION,
        namespace=namespace,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
        case_sensitive=case_sensitive,
    )
    packages_count = pkgdblib.search_package(
        SESSION,
        namespace=namespace,
        pkg_name=pattern,
        pkg_branch=branches,
        pkg_poc=owner,
        orphaned=orphaned,
        status=status,
        page=page,
        limit=limit,
        count=True,
        case_sensitive=case_sensitive,
    )
    total_page = int(ceil(packages_count / float(limit)))

    select = origin.replace('list_', '')
    if namespace:
        select = namespace

    if len(packages) == 1:
        flask.flash('Only one package matching, redirecting you to it')
        return flask.redirect(flask.url_for(
            '.package_info',
            namespace=packages[0].namespace,
            package=packages[0].name)
        )

    return flask.render_template(
        'list_packages.html',
        origin=origin,
        select=select,
        packages=packages,
        motif=pattern,
        total_page=total_page,
        packages_count=packages_count,
        page=page,
        status=status,
        owner=owner,
        branches=branches,
        namespace=namespace,
    )
예제 #46
0
def api_package_edit():
    '''
    Edit a package
    --------------
    Edit a package.

    ::

        /api/package/edit/

    Accepts POST queries only.

    :arg pkgname: String of the package name to be created.
    :arg summary: String of the summary description of the package.
    :arg description: String describing the package (same as in the
        spec file).
    :arg review_url: the URL of the package review on the bugzilla.
    :arg status: status of the package can be one of: 'Approved',
        'Awaiting Review', 'Denied', 'Obsolete', 'Removed'
    :arg upstream_url: the URL of the upstream project

    Sample response:

    ::

        {
          "output": "ok",
          "messages": ["Package edited"]
        }

        {
          "output": "notok",
          "error": ["You're not allowed to edit this package"]
        }

    '''
    httpcode = 200
    output = {}

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

    form = forms.EditPackageForm(
        csrf_enabled=False,
        pkg_status_list=pkg_status,
    )
    if form.validate_on_submit():
        pkg_name = form.pkgname.data

        package = None
        try:
            package = pkgdblib.search_package(SESSION, pkg_name, limit=1)[0]
        except (NoResultFound, IndexError):
            SESSION.rollback()
            output['output'] = 'notok'
            output['error'] = 'No package of this name found'
            httpcode = 500

        if package:
            pkg_summary = form.summary.data
            pkg_description = form.description.data
            pkg_review_url = form.review_url.data
            pkg_status = form.status.data
            if pkg_status == 'None':
                pkg_status = None
            pkg_upstream_url = form.upstream_url.data

            try:
                message = pkgdblib.edit_package(
                    SESSION,
                    package,
                    pkg_name=pkg_name,
                    pkg_summary=pkg_summary,
                    pkg_description=pkg_description,
                    pkg_review_url=pkg_review_url,
                    pkg_upstream_url=pkg_upstream_url,
                    pkg_status=pkg_status,
                    user=flask.g.fas_user)
                SESSION.commit()
                output['output'] = 'ok'
                output['messages'] = [message]
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                # We can only reach here in two cases:
                # 1) the user is not an admin, but that's taken care of
                #    by the decorator
                # 2) we have a SQLAlchemy problem when storing the info
                #    in the DB which we cannot test
                SESSION.rollback()
                output['output'] = 'notok'
                output['error'] = str(err)
                httpcode = 500
예제 #47
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
예제 #48
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)
예제 #49
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',
    )
예제 #50
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',
    )
예제 #51
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,
    )
예제 #52
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,
    )
예제 #53
0
def api_package_edit():
    '''
Edit a package
--------------
    Edit a package.

    ::

        /api/package/edit/

    Accept POST queries only.

    :arg pkgname: String of the package name to be created.
    :arg summary: String of the summary description of the package.
    :arg description: String describing the package (same as in the
        spec file).
    :arg review_url: the URL of the package review on the bugzilla.
    :arg status: status of the package can be one of: 'Approved',
        'Awaiting Review', 'Denied', 'Obsolete', 'Removed'
    :arg upstream_url: the URL of the upstream project

    Sample response:

    ::

        {
          "output": "ok",
          "messages": ["Package edited"]
        }

        {
          "output": "notok",
          "error": ["You're not allowed to edit this package"]
        }

    '''
    httpcode = 200
    output = {}

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

    form = forms.EditPackageForm(
        csrf_enabled=False,
        pkg_status_list=pkg_status,
    )
    if form.validate_on_submit():
        pkg_name = form.pkgname.data

        package = None
        try:
            package = pkgdblib.search_package(SESSION, pkg_name, limit=1)[0]
        except (NoResultFound, IndexError):
            SESSION.rollback()
            output['output'] = 'notok'
            output['error'] = 'No package of this name found'
            httpcode = 500

        if package:
            pkg_summary = form.summary.data
            pkg_description = form.description.data
            pkg_review_url = form.review_url.data
            pkg_status = form.status.data
            if pkg_status == 'None':
                pkg_status = None
            pkg_upstream_url = form.upstream_url.data

            try:
                message = pkgdblib.edit_package(
                    SESSION,
                    package,
                    pkg_name=pkg_name,
                    pkg_summary=pkg_summary,
                    pkg_description=pkg_description,
                    pkg_review_url=pkg_review_url,
                    pkg_upstream_url=pkg_upstream_url,
                    pkg_status=pkg_status,
                    user=flask.g.fas_user
                )
                SESSION.commit()
                output['output'] = 'ok'
                output['messages'] = [message]
            except pkgdblib.PkgdbException, err:  # pragma: no cover
                # We can only reach here in two cases:
                # 1) the user is not an admin, but that's taken care of
                #    by the decorator
                # 2) we have a SQLAlchemy problem when storing the info
                #    in the DB which we cannot test
                SESSION.rollback()
                output['output'] = 'notok'
                output['error'] = str(err)
                httpcode = 500
예제 #54
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,
    )
예제 #55
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,
    )
예제 #56
0
def api_package_list(pattern=None):
    '''
    List packages
    -------------
    List packages based on a pattern. If no pattern is provided, return all
    the package.

    ::

        /api/packages/<pattern>/

        /api/packages/?pattern=<pattern>

    Accepts GET queries only

    :arg pattern: Pattern to list packages from their name.
    :arg branches: List of string of the branches name in which these
        packages will be searched.
    :arg poc: String of the user name to to which restrict the search.
    :arg orphaned: Boolean to retrict the search to orphaned packages.
    :arg critpath: Boolean to retrict the search to critpath packages.
        Defaults to None which means results include both critpath and
        non-critpath packages.
    :arg status: Allows to filter packages based on their status: Approved,
        Orphaned, Retired, Removed.
    :arg acls: Boolean use to retrieve the acls in addition of the package
        information. Beware that this may reduce significantly the response
        time, it is advise to use it in combinaition with a specifir branch.
        Defaults to False.
    :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 limit: An integer to limit the number of results, defaults to
        250, maximum is 500.
    :kwarg page: The page number to return (useful in combination to limit).
    :kwarg count: A boolean to return the number of packages instead of the
        list. Defaults to False.

    *Results are paginated*

    Sample response:

    ::

        /api/packages/guak*

        {
          "output": "ok",
          "packages": [
            {
              "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": 1384775354.0,
                "review_url": null,
                "name": "guake"
            }
          ],
          "page_total": 1,
          "page": 1
        }

        /api/packages/cl*?status=Orphaned&branches=f20&acls=true

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "upstream_url": null,
              "description": "clive is a video extraction tool for "
                             "user-uploaded video hosts such as Youtube,"
                             "Google Video, Dailymotion, Guba, Metacafe "
                             "and Sevenload.It can be chained with 3rd "
                             "party tools for subsequent video re-encoding"
                             " and and playing.",
              "summary": "Video extraction tool for user-uploaded video hosts",
              "acls": [
                {
                  "status": "Retired",
                  "point_of_contact": "orphan",
                  "status_change": 1385363055.0,
                  "collection": {
                    "status": "Active",
                    "branchname": "f20",
                    "version": "20",
                    "name": "Fedora"
                  },
                  "package": null
                }
              ],
              "creation_date": 1385361948.0,
              "review_url": null,
              "name": "clive"
            }
          ],
          "page_total": 1,
          "page": 1
        }

    .. note:: the ``status_change`` and ``create_date`` fields are both
            timestamps expressed in
            `Unix TIME <https://en.wikipedia.org/wiki/Unix_time>`_

    '''
    httpcode = 200
    output = {}

    pattern = flask.request.args.get('pattern', pattern) or '*'
    branches = flask.request.args.getlist('branches', None)
    poc = flask.request.args.get('poc', None)
    orphaned = flask.request.args.get('orphaned', None)
    if str(orphaned).lower() in ['0', 'false']:
        orphaned = False
    elif orphaned is not None:
        orphaned = bool(orphaned)

    critpath = flask.request.args.get('critpath', None)
    if critpath and str(critpath).lower() in ['0', 'false']:
        critpath = False
    elif critpath:
        critpath = True
    acls = bool(flask.request.args.get('acls', False))
    statuses = flask.request.args.getlist('status', None)
    eol = flask.request.args.get('eol', False)
    page = flask.request.args.get('page', 1)
    limit = get_limit()
    count = flask.request.args.get('count', False)
    try:
        if not branches:
            branches = [None]
        if not statuses:
            statuses = [None]

        if count:
            packages = 0
            for status, branch in itertools.product(statuses, branches):
                packages += pkgdblib.search_package(
                    SESSION,
                    pkg_name=pattern,
                    pkg_branch=branch,
                    pkg_poc=poc,
                    orphaned=orphaned,
                    critpath=critpath,
                    status=status,
                    eol=eol,
                    page=page,
                    limit=limit,
                    count=count,
                )

            output['output'] = 'ok'
            output['packages'] = packages
            output['page'] = 1
            output['page_total'] = 1
        else:
            packages = set()
            packages_count = 0
            for status, branch in itertools.product(statuses, branches):
                packages.update(
                    pkgdblib.search_package(
                        SESSION,
                        pkg_name=pattern,
                        pkg_branch=branch,
                        pkg_poc=poc,
                        orphaned=orphaned,
                        critpath=critpath,
                        status=status,
                        eol=eol,
                        page=page,
                        limit=limit,
                        count=count,
                    ))
                packages_count += pkgdblib.search_package(
                    SESSION,
                    pkg_name=pattern,
                    pkg_branch=branch,
                    pkg_poc=poc,
                    orphaned=orphaned,
                    critpath=critpath,
                    status=status,
                    eol=eol,
                    page=page,
                    limit=limit,
                    count=True,
                )

            if not packages:
                output['output'] = 'notok'
                output['packages'] = []
                output['error'] = 'No packages found for these parameters'
                httpcode = 404
            else:
                output['packages'] = [
                    pkg.to_json(acls=acls, collection=branches, package=False)
                    for pkg in packages
                ]
                output['output'] = 'ok'
                output['page'] = int(page)
                output['page_total'] = int(ceil(packages_count / float(limit)))

    except pkgdblib.PkgdbException, err:
        SESSION.rollback()
        output['output'] = 'notok'
        output['error'] = str(err)
        httpcode = 500
예제 #57
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',
    )
예제 #58
0
def api_package_list(pattern=None):
    '''
List packages
-------------
    List packages based on a pattern. If no pattern is provided, return all
    the package.

    ::

        /api/packages/<pattern>/

        /api/packages/?pattern=<pattern>

    Accept GET queries only

    :arg pattern: Pattern to list packages from their name.
    :arg branches: List of string of the branches name in which these
        packages will be searched.
    :arg poc: String of the user name to to which restrict the search.
    :arg orphaned: Boolean to retrict the search to orphaned packages.
    :arg critpath: Boolean to retrict the search to critpath packages.
        Defaults to None which means results include both critpath and
        non-critpath packages.
    :arg status: Allows to filter packages based on their status: Approved,
        Orphaned, Retired, Removed.
    :arg acls: Boolean use to retrieve the acls in addition of the package
        information. Beware that this may reduce significantly the response
        time, it is advise to use it in combinaition with a specifir branch.
        Defaults to False.
    :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 limit: An integer to limit the number of results, defaults to
        250, maximum is 500.
    :kwarg page: The page number to return (useful in combination to limit).
    :kwarg count: A boolean to return the number of packages instead of the
        list. Defaults to False.

    *Results are paginated*

    Sample response:

    ::

        /api/packages/guak*

        {
          "output": "ok",
          "packages": [
            {
              "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": 1384775354.0,
                "review_url": null,
                "name": "guake"
            }
          ],
          "page_total": 1,
          "page": 1
        }

        /api/packages/cl*?status=Orphaned&branches=f20&acls=true

        {
          "output": "ok",
          "packages": [
            {
              "status": "Approved",
              "upstream_url": null,
              "description": "clive is a video extraction tool for "
                             "user-uploaded video hosts such as Youtube,"
                             "Google Video, Dailymotion, Guba, Metacafe "
                             "and Sevenload.It can be chained with 3rd "
                             "party tools for subsequent video re-encoding"
                             " and and playing.",
              "summary": "Video extraction tool for user-uploaded video hosts",
              "acls": [
                {
                  "status": "Retired",
                  "point_of_contact": "orphan",
                  "status_change": 1385363055.0,
                  "collection": {
                    "status": "Active",
                    "branchname": "f20",
                    "version": "20",
                    "name": "Fedora"
                  },
                  "package": null
                }
              ],
              "creation_date": 1385361948.0,
              "review_url": null,
              "name": "clive"
            }
          ],
          "page_total": 1,
          "page": 1
        }

    .. note:: the ``status_change`` and ``create_date`` fields are both
            timestamps expressed in
            `Unix TIME <https://en.wikipedia.org/wiki/Unix_time>`_

    '''
    httpcode = 200
    output = {}

    pattern = flask.request.args.get('pattern', pattern) or '*'
    branches = flask.request.args.getlist('branches', None)
    poc = flask.request.args.get('poc', None)
    orphaned = flask.request.args.get('orphaned', None)
    if str(orphaned).lower() in ['0', 'false']:
        orphaned = False
    elif orphaned is not None:
        orphaned = bool(orphaned)

    critpath = flask.request.args.get('critpath', None)
    if critpath and str(critpath).lower() in ['0', 'false']:
        critpath = False
    elif critpath:
        critpath = True
    acls = bool(flask.request.args.get('acls', False))
    statuses = flask.request.args.getlist('status', None)
    eol = flask.request.args.get('eol', False)
    page = flask.request.args.get('page', 1)
    limit = get_limit()
    count = flask.request.args.get('count', False)
    try:
        if not branches:
            branches = [None]
        if not statuses:
            statuses = [None]

        if count:
            packages = 0
            for status, branch in itertools.product(
                    statuses, branches):
                packages += pkgdblib.search_package(
                    SESSION,
                    pkg_name=pattern,
                    pkg_branch=branch,
                    pkg_poc=poc,
                    orphaned=orphaned,
                    critpath=critpath,
                    status=status,
                    eol=eol,
                    page=page,
                    limit=limit,
                    count=count,
                )

            output['output'] = 'ok'
            output['packages'] = packages
            output['page'] = 1
            output['page_total'] = 1
        else:
            packages = set()
            packages_count = 0
            for status, branch in itertools.product(
                    statuses, branches):
                packages.update(
                    pkgdblib.search_package(
                        SESSION,
                        pkg_name=pattern,
                        pkg_branch=branch,
                        pkg_poc=poc,
                        orphaned=orphaned,
                        critpath=critpath,
                        status=status,
                        eol=eol,
                        page=page,
                        limit=limit,
                        count=count,
                    )
                )
                packages_count += pkgdblib.search_package(
                    SESSION,
                    pkg_name=pattern,
                    pkg_branch=branch,
                    pkg_poc=poc,
                    orphaned=orphaned,
                    critpath=critpath,
                    status=status,
                    eol=eol,
                    page=page,
                    limit=limit,
                    count=True,
                )

            if not packages:
                output['output'] = 'notok'
                output['packages'] = []
                output['error'] = 'No packages found for these parameters'
                httpcode = 404
            else:
                output['packages'] = [
                    pkg.to_json(acls=acls, collection=branches, package=False)
                    for pkg in packages
                ]
                output['output'] = 'ok'
                output['page'] = int(page)
                output['page_total'] = int(ceil(packages_count / float(limit)))

    except pkgdblib.PkgdbException, err:
        SESSION.rollback()
        output['output'] = 'notok'
        output['error'] = str(err)
        httpcode = 500
예제 #59
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,
    )