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
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)})
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))
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))
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))
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)
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))
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())})
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()))
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)
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))
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))
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))
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)))