def update_from_names(cls, user, copr, names): UsersLogic.raise_if_cant_update_copr( user, copr, "Only owners and admins may update their projects.") current_chroots = copr.mock_chroots new_chroots = cls.mock_chroots_from_names(names) # add non-existing run_createrepo = False for mock_chroot in new_chroots: if mock_chroot not in current_chroots: db.session.add( models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) run_createrepo = True if run_createrepo: ActionsLogic.send_createrepo(copr) # delete no more present to_remove = [] for mock_chroot in current_chroots: if mock_chroot in new_chroots: continue if not mock_chroot.is_active: continue # can't delete here, it would change current_chroots and break # iteration to_remove.append(mock_chroot) for mc in to_remove: copr.mock_chroots.remove(mc)
def activate_group(fas_group): form = ActivateFasGroupForm() if form.validate_on_submit(): if UsersLogic.is_blacklisted_group(fas_group): flask.flash("This group is blacklisted and cannot be added.") return flask.redirect(url_for( "groups_ns.list_user_groups")) if fas_group not in flask.g.user.user_teams: raise InsufficientRightsException( "User '{}' doesn't have access to fas group {}" .format(flask.g.user.username, fas_group)) alias = form.name.data group = UsersLogic.get_group_by_fas_name_or_create( fas_group, alias) db.session.add(group) db.session.commit() flask.flash( "FAS group {} is activated in the Copr under the alias {} " .format(fas_group, alias) ) return flask.redirect(url_for( "groups_ns.list_projects_by_group", group_name=alias)) else: return flask.render_template( "groups/activate_fas_group.html", fas_group=fas_group, form=form, user=flask.g.user, )
def copr_edit_package_post(copr, package_name): UsersLogic.raise_if_cant_build_in_copr( flask.g.user, copr, "You don't have permissions to edit this package.") url_on_success = helpers.copr_url("coprs_ns.copr_packages", copr) return process_save_package(copr, package_name, view="coprs_ns.copr_edit_package", view_method=copr_edit_package, url_on_success=url_on_success)
def activate_group(fas_group): form = ActivateFasGroupForm() if form.validate_on_submit(): if UsersLogic.is_blacklisted_group(fas_group): flask.flash("This group is blacklisted and cannot be added.") return flask.redirect(url_for("groups_ns.list_user_groups")) if fas_group not in flask.g.user.user_teams: raise InsufficientRightsException( "User '{}' doesn't have access to fas group {}".format( flask.g.user.username, fas_group)) alias = form.name.data group = UsersLogic.get_group_by_fas_name_or_create(fas_group, alias) db.session.add(group) db.session.commit() flask.flash( "FAS group {} is activated in the Copr under the alias {} ".format( fas_group, alias)) return flask.redirect( url_for("groups_ns.list_projects_by_group", group_name=alias)) else: return flask.render_template( "groups/activate_fas_group.html", fas_group=fas_group, form=form, user=flask.g.user, )
def decorated_function(*args, **kwargs): token = None apt_login = None if "Authorization" in flask.request.headers: base64string = flask.request.headers["Authorization"] base64string = base64string.split()[1].strip() userstring = base64.b64decode(base64string) (apt_login, token) = userstring.decode("utf-8").split(":") token_auth = False if token and apt_login: user = UsersLogic.get_by_api_login(apt_login).first() if (user and user.api_token == token and user.api_token_expiration >= datetime.date.today()): if user.proxy and "username" in flask.request.form: user = UsersLogic.get( flask.request.form["username"]).first() token_auth = True flask.g.user = user if not token_auth: url = 'https://' + app.config["PUBLIC_COPR_HOSTNAME"] url = helpers.fix_protocol_for_frontend(url) output = { "output": "notok", "error": "Login invalid/expired. Please visit {0}/api to get or renew your API token." .format(url), } jsonout = flask.jsonify(output) jsonout.status_code = 401 return jsonout return f(*args, **kwargs)
def add(cls, user, name, selected_chroots, repos=None, description=None, instructions=None, check_for_duplicates=False, group=None, **kwargs): copr = models.Copr(name=name, repos=repos or u"", owner_id=user.id, description=description or u"", instructions=instructions or u"", created_on=int(time.time()), **kwargs) if group is not None: UsersLogic.raise_if_not_in_group(user, group) copr.group = group # form validation checks for duplicates CoprsLogic.new(user, copr, check_for_duplicates=check_for_duplicates) CoprChrootsLogic.new_from_names(copr, selected_chroots) db.session.flush() ActionsLogic.send_create_gpg_key(copr) return copr
def create_chroot(cls, user, copr, mock_chroot, buildroot_pkgs=None, repos=None, comps=None, comps_name=None, with_opts="", without_opts="", delete_after=None, delete_notify=None): """ :type user: models.User :type mock_chroot: models.MockChroot """ if buildroot_pkgs is None: buildroot_pkgs = "" if repos is None: repos = "" UsersLogic.raise_if_cant_update_copr( user, copr, "Only owners and admins may update their projects.") chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, chroot, with_opts, without_opts, delete_after, delete_notify) return chroot
def copr_edit_package_post(copr, package_name, source_type_text): UsersLogic.raise_if_cant_build_in_copr( flask.g.user, copr, "You don't have permissions to edit this package.") url_on_success = helpers.copr_url("coprs_ns.copr_packages", copr) return process_save_package(copr, source_type_text, package_name, view="coprs_ns.copr_edit_package", view_method=copr_edit_package, url_on_success=url_on_success)
def test_group_add_alias_with_space(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[0] alias = "alias_1 foo bar" assert not UsersLogic.group_alias_exists(alias) r = self.test_client.post("/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True) assert not UsersLogic.group_alias_exists(alias)
def remove_copr_chroot(cls, user, copr_chroot): """ :param models.CoprChroot chroot: """ UsersLogic.raise_if_cant_update_copr( user, copr_chroot.copr, "Only owners and admins may update their projects.") db.session.delete(copr_chroot)
def remove_comps(cls, user, copr_chroot): UsersLogic.raise_if_cant_update_copr( user, copr_chroot.copr, "Only owners and admins may update their projects.") copr_chroot.comps_name = None copr_chroot.comps_zlib = None ActionsLogic.send_update_comps(copr_chroot) db.session.add(copr_chroot)
def test_group_add_not_in_fas_group(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[3] alias = "alias_1" assert not UsersLogic.group_alias_exists(alias) r = self.test_client.post("/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True) # assert r.status_code == 403 assert not UsersLogic.group_alias_exists(alias)
def test_group_add_alias_with_space(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[0] alias = "alias_1 foo bar" assert not UsersLogic.group_alias_exists(alias) r = self.test_client.post( "/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True ) assert not UsersLogic.group_alias_exists(alias)
def test_group_add_not_in_fas_group(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[3] alias = "alias_1" assert not UsersLogic.group_alias_exists(alias) r = self.test_client.post( "/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True ) # assert r.status_code == 403 assert not UsersLogic.group_alias_exists(alias)
def coprs_migration_report(username=None): if not username and not flask.g.user: return generic_error("You are not logged in") elif not username: username = flask.g.user.name user = UsersLogic.get(username).first() coprs = CoprsLogic.filter_without_group_projects(CoprsLogic.get_multiple_owned_by_username(username)).all() for group in UsersLogic.get_groups_by_fas_names_list(user.user_teams).all(): coprs.extend(CoprsLogic.get_multiple_by_group_id(group.id).all()) return render_migration_report(coprs, user=user)
def list_user_groups(): teams = flask.g.user.user_teams active_map = { group.fas_name: group.name for group in UsersLogic.get_groups_by_fas_names_list(teams).all() } teams = UsersLogic.filter_blacklisted_teams(teams) copr_groups = {fas_name: active_map.get(fas_name) for fas_name in teams} return render_template("groups/user_fas_groups.html", user=flask.g.user, teams=teams, copr_groups=copr_groups)
def test_group_add_twice(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[0] alias = "alias_1" assert not UsersLogic.group_alias_exists(alias) self.test_client.post("/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True) assert UsersLogic.group_alias_exists(alias) assert len(models.Group.query.all()) == 1 self.test_client.post("/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True) assert len(models.Group.query.all()) == 1
def add(cls, user, name, selected_chroots, repos=None, description=None, instructions=None, check_for_duplicates=False, group=None, persistent=False, auto_prune=True, use_bootstrap_container=False, follow_fedora_branching=False, **kwargs): if not user.admin and persistent: raise exceptions.NonAdminCannotCreatePersistentProject() if not user.admin and not auto_prune: raise exceptions.NonAdminCannotDisableAutoPrunning() # form validation checks for duplicates cls.new(user, name, group, check_for_duplicates=check_for_duplicates) copr = models.Copr(name=name, repos=repos or u"", user=user, description=description or u"", instructions=instructions or u"", created_on=int(time.time()), persistent=persistent, auto_prune=auto_prune, use_bootstrap_container=use_bootstrap_container, follow_fedora_branching=follow_fedora_branching, **kwargs) if group is not None: UsersLogic.raise_if_not_in_group(user, group) copr.group = group copr_dir = models.CoprDir(main=True, name=name, copr=copr) db.session.add(copr_dir) db.session.add(copr) CoprChrootsLogic.new_from_names(copr, selected_chroots) db.session.flush() ActionsLogic.send_create_gpg_key(copr) return copr
def update_chroot(cls, user, copr_chroot, buildroot_pkgs, comps=None, comps_name=None): """ :type user: models.User :type copr_chroot: models.CoprChroot """ UsersLogic.raise_if_cant_update_copr( user, copr_chroot.copr, "Only owners and admins may update their projects.") cls._update_chroot(buildroot_pkgs, comps, comps_name, copr_chroot) db.session.add(copr_chroot) return copr_chroot
def coprs_migration_report(username=None): if not username and not flask.g.user: return generic_error("You are not logged in") elif not username: username = flask.g.user.name user = UsersLogic.get(username).first() coprs = CoprsLogic.filter_without_group_projects( CoprsLogic.get_multiple_owned_by_username(username)).all() for group in UsersLogic.get_groups_by_fas_names_list( user.user_teams).all(): coprs.extend(CoprsLogic.get_multiple_by_group_id(group.id).all()) return render_migration_report(coprs, user=user)
def process_pinned_projects_post(owner, url_on_success): if isinstance(owner, models.Group): UsersLogic.raise_if_not_in_group(flask.g.user, owner) form = PinnedCoprsForm() if not form.validate_on_submit(): return render_pinned_projects(owner, form=form) PinnedCoprsLogic.delete_by_owner(owner) for i, copr_id in enumerate(filter(None, form.copr_ids.data)): PinnedCoprsLogic.add(owner, int(copr_id), i) db.session.commit() return flask.redirect(url_on_success)
def create_chroot(cls, user, copr, mock_chroot, buildroot_pkgs=None, comps=None, comps_name=None): """ :type user: models.User :type mock_chroot: models.MockChroot """ if buildroot_pkgs is None: buildroot_pkgs = "" UsersLogic.raise_if_cant_update_copr( user, copr, "Only owners and admins may update their projects.") chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) cls._update_chroot(buildroot_pkgs, comps, comps_name, chroot) return chroot
def decorated_function(*args, **kwargs): token = None apt_login = None if "Authorization" in flask.request.headers: base64string = flask.request.headers["Authorization"] base64string = base64string.split()[1].strip() userstring = base64.b64decode(base64string) (apt_login, token) = userstring.decode("utf-8").split(":") token_auth = False if token and apt_login: user = UsersLogic.get_by_api_login(apt_login).first() if (user and user.api_token == token and user.api_token_expiration >= datetime.date.today()): token_auth = True flask.g.user = user if not token_auth: output = { "output": "notok", "error": "Login invalid/expired. " "Please visit https://copr.fedoraproject.org/api " "get or renew your API token.", } jsonout = flask.jsonify(output) jsonout.status_code = 500 return jsonout return f(*args, **kwargs)
def decorated_function(*args, **kwargs): token = None apt_login = None if "Authorization" in flask.request.headers: base64string = flask.request.headers["Authorization"] base64string = base64string.split()[1].strip() userstring = base64.b64decode(base64string) (apt_login, token) = userstring.split(":") token_auth = False if token and apt_login: user = UsersLogic.get_by_api_login(apt_login).first() if (user and user.api_token == token and user.api_token_expiration >= datetime.date.today()): token_auth = True flask.g.user = user if not token_auth: output = { "output": "notok", "error": "Login invalid/expired. " "Please visit https://copr.fedoraproject.org/api " "get or renew your API token.", } jsonout = flask.jsonify(output) jsonout.status_code = 500 return jsonout return f(*args, **kwargs)
def get_active_groups_by_user(user_name): names = flask.g.user.user_groups if names: query = UsersLogic.get_groups_by_names_list(names) return query.filter(User.name == user_name) else: return []
def decorated_function(*args, **kwargs): token = None apt_login = None if "Authorization" in flask.request.headers: base64string = flask.request.headers["Authorization"] base64string = base64string.split()[1].strip() userstring = base64.b64decode(base64string) (apt_login, token) = userstring.decode("utf-8").split(":") token_auth = False if token and apt_login: user = UsersLogic.get_by_api_login(apt_login).first() if (user and user.api_token == token and user.api_token_expiration >= datetime.date.today()): token_auth = True flask.g.user = user if not token_auth: output = { "output": "notok", "error": "Login invalid/expired. Please visit {0}/api to get or renew your API token." .format(app.config["FRONTEND_BASE_URL"]), } jsonout = flask.jsonify(output) jsonout.status_code = 500 return jsonout return f(*args, **kwargs)
def get_group_by_name_safe(group_name): try: group = UsersLogic.get_group_by_alias(group_name).one() except sqlalchemy.orm.exc.NoResultFound: raise ObjectNotFound( message="Group {} does not exist.".format(group_name)) return group
def test_group_add_twice(self, f_users, f_fas_groups, f_db): fas_name = f_fas_groups[0] alias = "alias_1" assert not UsersLogic.group_alias_exists(alias) self.test_client.post( "/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True ) assert UsersLogic.group_alias_exists(alias) assert len(models.Group.query.all()) == 1 self.test_client.post( "/groups/activate/{}".format(fas_name), data={"name": alias}, follow_redirects=True ) assert len(models.Group.query.all()) == 1
def list_user_groups(): teams = flask.g.user.user_teams active_map = { group.fas_name: group.name for group in UsersLogic.get_groups_by_fas_names_list(teams).all() } teams = UsersLogic.filter_blacklisted_teams(teams) copr_groups = { fas_name: active_map.get(fas_name) for fas_name in teams } return render_template( "groups/user_fas_groups.html", user=flask.g.user, teams=teams, copr_groups=copr_groups)
def add(cls, user, name, selected_chroots, repos=None, description=None, instructions=None, check_for_duplicates=False, group=None, **kwargs): copr = models.Copr(name=name, repos=repos or u"", owner_id=user.id, description=description or u"", instructions=instructions or u"", created_on=int(time.time()), **kwargs) if group is not None: UsersLogic.raise_if_not_in_group(user, group) copr.group = group # form validation checks for duplicates CoprsLogic.new(user, copr, check_for_duplicates=check_for_duplicates) CoprChrootsLogic.new_from_names(copr, selected_chroots) return copr
def update_from_names(cls, user, copr, names): UsersLogic.raise_if_cant_update_copr( user, copr, "Only owners and admins may update their projects.") current_chroots = copr.mock_chroots new_chroots = cls.mock_chroots_from_names(names) # add non-existing for mock_chroot in new_chroots: if mock_chroot not in current_chroots: db.session.add( models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) # delete no more present to_remove = [] for mock_chroot in current_chroots: if mock_chroot not in new_chroots: # can't delete here, it would change current_chroots and break # iteration to_remove.append(mock_chroot) for mc in to_remove: copr.mock_chroots.remove(mc)
def render_pinned_projects(owner, form=None): pinned = [pin.copr for pin in PinnedCoprsLogic.get_by_owner(owner)] if isinstance(owner, models.Group): UsersLogic.raise_if_not_in_group(flask.g.user, owner) coprs = CoprsLogic.get_multiple_by_group_id(owner.id).filter( models.Copr.unlisted_on_hp.is_(False)).all() else: coprs = ComplexLogic.get_coprs_permissible_by_user(owner) coprs = sorted(coprs, key=lambda copr: copr.full_name) selected = [copr.id for copr in pinned] selected += (app.config["PINNED_PROJECTS_LIMIT"] - len(pinned)) * [None] for i, copr_id in enumerate(form.copr_ids.data if form else []): selected[i] = int(copr_id) if copr_id else None graph = BuildsLogic.get_small_graph_data('30min') return flask.render_template("pinned.html", owner=owner, pinned=pinned, selected=selected, coprs=coprs, form=form, tasks_info=ComplexLogic.get_queue_sizes(), graph=graph)
def raise_if_cant_delete(cls, user, copr): """ Raise InsufficientRightsException if given copr cant be deleted by given user. Return None otherwise. """ if user.admin: return if copr.group: return UsersLogic.raise_if_not_in_group(user, copr.group) if user == copr.user: return raise exceptions.InsufficientRightsException( "Only owners may delete their projects.")
def test_raise_if_cant_delete(self, f_users, f_fas_groups, f_coprs): # Project owner should be able to delete his project CoprsLogic.raise_if_cant_delete(self.u2, self.c2) # Admin should be able to delete everything CoprsLogic.raise_if_cant_delete(self.u1, self.c2) # A user can't remove someone else's project with pytest.raises(InsufficientRightsException): CoprsLogic.raise_if_cant_delete(self.u2, self.c1) # Group member should be able to remove group project self.u2.openid_groups = {"fas_groups": ["somegroup"]} self.u3.openid_groups = {"fas_groups": ["somegroup"]} self.c2.group = UsersLogic.get_group_by_fas_name_or_create("somegroup") CoprsLogic.raise_if_cant_delete(self.u3, self.c2) # Once a member is kicked from a group, he can't delete # a project even though he originally created it self.u2.openid_groups = {"fas_groups": []} with pytest.raises(InsufficientRightsException): CoprsLogic.raise_if_cant_delete(self.u2, self.c2)
def __call__(self, form, field): if UsersLogic.group_alias_exists(field.data): raise wtforms.ValidationError(self.message.format(field.data))
def delete_data(): UsersLogic.delete_user_data(flask.g.user.username) flask.flash("Your data were successfully deleted.") return render_user_info(flask.g.user)
def test_delete_user_data(self, f_users, f_fas_groups, f_coprs, f_db): UsersLogic.delete_user_data(self.u1) self.db.session.commit() user = UsersLogic.get(self.u1.username).one() assert not user.admin assert not user.api_login
def test_delete_data_view(self, f_users, f_fas_groups, f_coprs, f_db): r = self.tc.get("/user/delete") user = UsersLogic.get(self.u1.username).one() assert not user.admin assert not user.api_login
def delete_data(): UsersLogic.delete_user_data(flask.g.user) db.session.commit() flask.flash("Your data were successfully deleted.") return render_user_info(flask.g.user)