コード例 #1
0
    def request_permission(cls, copr, user, permission, req_bool):
        approved = helpers.PermissionEnum('approved')
        state = None
        if req_bool is True:
            state = 'request'
        elif req_bool is False:
            state = 'nothing'
        else:
            raise BadRequest("invalid '{0}' permission request '{1}', "
                             "expected True or False".format(
                                 permission, req_bool))

        cls.validate_permission(user, copr, permission, state)
        perm_o = models.CoprPermission(user_id=user.id, copr_id=copr.id)
        perm_o = db.session.merge(perm_o)
        old_state = perm_o.get_permission(permission)
        if old_state == approved and state == 'request':
            raise BadRequest("You already are '{0}' in '{1}'".format(
                permission, copr.full_name))

        new_state = helpers.PermissionEnum(state)
        perm_o.set_permission(permission, new_state)

        if old_state != new_state:
            return (old_state, new_state)
        return None
コード例 #2
0
ファイル: apiv3_permissions.py プロジェクト: praiskup/copr
def request_permissions(ownername, projectname):
    copr = get_copr(ownername, projectname)
    roles = flask.request.get_json()
    if not isinstance(roles, dict):
        raise BadRequest("invalid 'roles' dict format, expected: "
                         "{'admin': True, 'builder': False}")
    if not roles:
        raise BadRequest("no permission requested")

    permission_dict = {}
    with db_session_scope():
        for permission, request_bool in roles.items():
            change = CoprPermissionsLogic.request_permission(
                copr, flask.g.user, permission, request_bool)
            if change:
                permission_dict['old_' + permission] = change[0]
                permission_dict['new_' + permission] = change[1]

    if permission_dict:
        msg = PermissionRequestMessage(copr, flask.g.user, permission_dict)
        for address in copr.admin_mails:
            if flask.current_app.config.get("SEND_EMAILS", False):
                send_mail([address], msg)

    return flask.jsonify({'updated': bool(permission_dict)})
コード例 #3
0
    def validate_permission(cls, user, copr, permission, state):
        allowed = ['admin', 'builder']
        if permission not in allowed:
            raise BadRequest("invalid permission '{0}', allowed {1}".format(
                permission, '|'.join(allowed)))

        allowed = helpers.PermissionEnum.vals.keys()
        if state not in allowed:
            raise BadRequest("invalid '{0}' permission state '{1}', "
                             "use {2}".format(permission, state,
                                              '|'.join(allowed)))

        if user.id == copr.user_id:
            raise BadRequest("user '{0}' is owner of the '{1}' "
                             "project".format(user.name, copr.full_name))
コード例 #4
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def edit_project(ownername, projectname):
    copr = get_copr(ownername, projectname)
    data = rename_fields(get_form_compatible_data())
    form = forms.CoprModifyForm(data, meta={'csrf': False})

    if not form.validate_on_submit():
        raise BadRequest(form.errors)
    validate_chroots(get_input_dict(), MockChrootsLogic.get_multiple())

    for field in form:
        if field.data is None or field.name in ["csrf_token", "chroots"]:
            continue
        if field.name not in data.keys():
            continue
        setattr(copr, field.name, field.data)

    if form.chroots.data:
        CoprChrootsLogic.update_from_names(flask.g.user, copr,
                                           form.chroots.data)

    try:
        CoprsLogic.update(flask.g.user, copr)
        if copr.group:  # load group.id
            _ = copr.group.id
        db.session.commit()
    except (ActionInProgressException, InsufficientRightsException,
            NonAdminCannotDisableAutoPrunning) as ex:
        db.session.rollback()
        raise ex

    return flask.jsonify(to_dict(copr))
コード例 #5
0
def edit_project_chroot(ownername, projectname, chrootname):
    copr = get_copr(ownername, projectname)
    data = rename_fields(get_form_compatible_data())
    form = forms.ModifyChrootForm(data, meta={'csrf': False})
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chrootname)

    if not form.validate_on_submit():
        raise BadRequest(form.errors)

    buildroot_pkgs = repos = comps_xml = comps_name = with_opts = without_opts = None
    if "buildroot_pkgs" in data:
        buildroot_pkgs = form.buildroot_pkgs.data
    if "repos" in data:
        repos = form.repos.data
    if "with_opts" in data:
        with_opts = form.with_opts.data
    if "without_opts" in data:
        without_opts = form.without_opts.data
    if form.upload_comps.has_file():
        comps_xml = form.upload_comps.data.stream.read()
        comps_name = form.upload_comps.data.filename
    if form.delete_comps.data:
        CoprChrootsLogic.remove_comps(flask.g.user, chroot)
    CoprChrootsLogic.update_chroot(flask.g.user,
                                   chroot,
                                   buildroot_pkgs,
                                   repos,
                                   comps=comps_xml,
                                   comps_name=comps_name,
                                   with_opts=with_opts,
                                   without_opts=without_opts)
    db.session.commit()
    return flask.jsonify(to_dict(chroot))
コード例 #6
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def search_projects(query, **kwargs):
    try:
        search_query = CoprsLogic.get_multiple_fulltext(query)
        paginator = Paginator(search_query, models.Copr, **kwargs)
        projects = paginator.map(to_dict)
    except ValueError as ex:
        raise BadRequest(str(ex))
    return flask.jsonify(items=projects, meta=paginator.meta)
コード例 #7
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def fork_project(ownername, projectname):
    copr = get_copr(ownername, projectname)

    # @FIXME we want "ownername" from the outside, but our internal Form expects "owner" instead
    data = get_form_compatible_data()
    data["owner"] = data.get("ownername")

    form = forms.CoprForkFormFactory \
        .create_form_cls(copr=copr, user=flask.g.user, groups=flask.g.user.user_groups)(data, meta={'csrf': False})

    if form.validate_on_submit() and copr:
        try:
            dstgroup = ([
                g for g in flask.g.user.user_groups
                if g.at_name == form.owner.data
            ] or [None])[0]
            if flask.g.user.name != form.owner.data and not dstgroup:
                return ObjectNotFound("There is no such group: {}".format(
                    form.owner.data))

            fcopr, created = ComplexLogic.fork_copr(copr,
                                                    flask.g.user,
                                                    dstname=form.name.data,
                                                    dstgroup=dstgroup)
            if not created and form.confirm.data != True:
                raise BadRequest(
                    "You are about to fork into existing project: {}\n"
                    "Please use --confirm if you really want to do this".
                    format(fcopr.full_name))
            db.session.commit()

        except (ActionInProgressException, InsufficientRightsException) as err:
            db.session.rollback()
            raise err
    else:
        raise BadRequest(form.errors)

    return flask.jsonify(to_dict(fcopr))
コード例 #8
0
ファイル: apiv3_permissions.py プロジェクト: praiskup/copr
def set_permissions(copr):
    permissions = flask.request.get_json()
    if not isinstance(permissions, dict):
        raise BadRequest(
            "request is not a dictionary, expected format: "
            "{'username': {'admin': 'nothing', 'builder': 'request'} ...}")

    if not permissions:
        raise BadRequest("no permission change requested")

    updated = {}
    messages = []
    with db_session_scope():
        for username, perm_set in permissions.items():
            user = models.User.query.filter_by(username=username).first()
            if not user:
                raise BadRequest(
                    "user '{0}' doesn't exist in database".format(username))

            permission_dict = {}
            for perm, state in perm_set.items():
                change = CoprPermissionsLogic.set_permissions(
                    flask.g.user, copr, user, perm, state)
                if change:
                    updated[username] = True
                    permission_dict['old_' + perm] = change[0]
                    permission_dict['new_' + perm] = change[1]

            if permission_dict:
                msg = PermissionChangeMessage(copr, permission_dict)
                messages.append({'address': user.mail, 'message': msg})

    # send emails only if transaction succeeded
    for task in messages:
        if flask.current_app.config.get("SEND_EMAILS", False):
            send_mail([task['address']], task['message'])

    return flask.jsonify({'updated': list(updated.keys())})
コード例 #9
0
ファイル: apiv3_modules.py プロジェクト: schlupov/copr
def build_module(ownername, projectname):
    copr = get_copr(ownername, projectname)
    form = forms.ModuleBuildForm(meta={'csrf': False})
    if not form.validate_on_submit():
        raise BadRequest(form.errors)

    facade = None
    try:
        mod_info = ModuleProvider.from_input(form.modulemd.data
                                             or form.scmurl.data)
        facade = ModuleBuildFacade(flask.g.user, copr, mod_info.yaml,
                                   mod_info.filename)
        module = facade.submit_build()
        db.session.commit()
        return flask.jsonify(to_dict(module))

    except (ValidationError, RequestException, InvalidSchema) as ex:
        raise BadRequest(str(ex))

    except sqlalchemy.exc.IntegrityError:
        raise DuplicateException("Module {}-{}-{} already exists".format(
            facade.modulemd.get_name(), facade.modulemd.get_stream(),
            facade.modulemd.get_version()))
コード例 #10
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def delete_project(ownername, projectname):
    copr = get_copr(ownername, projectname)
    copr_dict = to_dict(copr)
    form = forms.APICoprDeleteForm(meta={'csrf': False})

    if form.validate_on_submit() and copr:
        try:
            ComplexLogic.delete_copr(copr)
        except (ActionInProgressException, InsufficientRightsException) as err:
            db.session.rollback()
            raise err
        else:
            db.session.commit()
    else:
        raise BadRequest(form.errors)
    return flask.jsonify(copr_dict)
コード例 #11
0
ファイル: apiv3_builds.py プロジェクト: schlupov/copr
def process_creating_new_build(copr, form, create_new_build):
    if not form.validate_on_submit():
        raise BadRequest("Bad request parameters: {0}".format(form.errors))

    if not flask.g.user.can_build_in(copr):
        raise AccessRestricted("User {} is not allowed to build in the copr: {}"
                               .format(flask.g.user.username, copr.full_name))

    # From URLs it can be created multiple builds at once
    # so it can return a list
    build = create_new_build()
    db.session.commit()

    if type(build) == list:
        builds = [build] if type(build) != list else build
        return flask.jsonify(items=[to_dict(b) for b in builds], meta={})
    return flask.jsonify(to_dict(build))
コード例 #12
0
ファイル: apiv3_packages.py プロジェクト: schlupov/copr
def package_build():
    copr = get_copr()
    data = rename_fields(get_form_compatible_data(preserve=["python_versions"]))
    form = forms.RebuildPackageFactory.create_form_cls(copr.active_chroots)(data, meta={'csrf': False})
    try:
        package = PackagesLogic.get(copr.main_dir.id, form.package_name.data)[0]
    except IndexError:
        raise ObjectNotFound("No package with name {name} in copr {copr}"
                             .format(name=form.package_name.data, copr=copr.name))
    if form.validate_on_submit():
        buildopts = {k: v for k, v in form.data.items() if k in data}
        build = PackagesLogic.build_package(flask.g.user, copr, package, form.selected_chroots,
                                            copr_dirname=form.project_dirname.data, **buildopts)
        db.session.commit()
    else:
        raise BadRequest(form.errors)
    return flask.jsonify(build_to_dict(build))
コード例 #13
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def add_project(ownername):
    data = rename_fields(get_form_compatible_data())
    form = forms.CoprFormFactory.create_form_cls()(data, meta={'csrf': False})

    if not form.validate_on_submit():
        raise BadRequest(form.errors)
    validate_chroots(get_input_dict(), MockChrootsLogic.get_multiple())

    group = None
    if ownername[0] == "@":
        group = ComplexLogic.get_group_by_name_safe(ownername[1:])

    try:
        copr = CoprsLogic.add(
            name=form.name.data.strip(),
            repos=" ".join(form.repos.data.split()),
            user=flask.g.user,
            selected_chroots=form.selected_chroots,
            description=form.description.data,
            instructions=form.instructions.data,
            check_for_duplicates=True,
            unlisted_on_hp=form.unlisted_on_hp.data,
            build_enable_net=form.enable_net.data,
            group=group,
            persistent=form.persistent.data,
            auto_prune=form.auto_prune.data,
            use_bootstrap_container=form.use_bootstrap_container.data,
            homepage=form.homepage.data,
            contact=form.contact.data,
            disable_createrepo=form.disable_createrepo.data,
            delete_after_days=form.delete_after_days.data,
            multilib=form.multilib.data,
            module_hotfixes=form.module_hotfixes.data,
        )
        db.session.commit()
    except (DuplicateException, NonAdminCannotCreatePersistentProject,
            NonAdminCannotDisableAutoPrunning) as err:
        db.session.rollback()
        raise err
    return flask.jsonify(to_dict(copr))
コード例 #14
0
ファイル: apiv3_projects.py プロジェクト: praiskup/copr
def validate_chroots(input, allowed_chroots):
    inserted = set(input["chroots"] or [])
    allowed = {x.name for x in allowed_chroots}
    unexpected = inserted - allowed
    if unexpected:
        raise BadRequest("Unexpected chroot: {}".format(", ".join(unexpected)))