diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index 26df8205bc38c3ae7d73b19af1c8e4ee5f2c38c5..083eefb84ca324ff0892fbafaa4ac920ca634a82 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -16,7 +16,6 @@ from mo.csv import FileFormat import mo.db as db from mo.imports import ImportType, create_import import mo.jobs.submit -import mo.rights from mo.rights import Right, Rights import mo.util from mo.util_format import inflect_number @@ -78,11 +77,9 @@ class ParticipantsActionForm(FlaskForm): remove_participation = wtforms.SubmitField("Smazat záznam o účasti") - def do_action(self, round: db.Round, rights: Rights, query: Query) -> bool: + def do_action(self, round: db.Round, query: Query) -> bool: """Do participation modification on partipations from given query - (possibly filtered by checkboxes). `rights` param is used to check rights - for contest of each modified participation or for contest in which - participation is moved to.""" + (possibly filtered by checkboxes).""" if not self.validate_on_submit(): return False @@ -106,8 +103,8 @@ class ParticipantsActionForm(FlaskForm): if not contest: flash(f"Nepovedlo se najít soutěž v kole {round.round_code()} v oblasti {contest_place.name}", 'danger') return False - rights.get_for_contest(contest) - if not rights.have_right(Right.manage_contest): + rr = g.gatekeeper.rights_for_contest(contest) + if not rr.have_right(Right.manage_contest): flash(f"Nemáte právo ke správě soutěže v kole {round.round_code()} v oblasti {contest_place.name}, nelze do ní přesunout účastníky", 'danger') return False elif self.remove_participation.data: @@ -124,22 +121,17 @@ class ParticipantsActionForm(FlaskForm): # Check all participations if we can edit them ctants = query.all() - rights_cache = set() for pion, _, _ in ctants: u = pion.user if self.action_on.data == 'checked' and u.user_id not in user_ids: continue - if pion.contest_id in rights_cache: - continue - rights.get_for_contest(pion.contest) - if rights.have_right(Right.manage_contest): - rights_cache.add(pion.contest_id) - continue - flash( - f"Nemáte právo ke správě soutěže v kole {round.round_code()} v oblasti {pion.contest.place.name} " - + f"(účastník {u.full_name()}). Žádná akce nebyla provedena.", 'danger' - ) - return False + rr = g.gatekeeper.rights_for_contest(pion.contest) + if not rr.have_right(Right.manage_contest): + flash( + f"Nemáte právo ke správě soutěže v kole {round.round_code()} v oblasti {pion.contest.place.name} " + + f"(účastník {u.full_name()}). Žádná akce nebyla provedena.", 'danger' + ) + return False count = 0 for pion, _, _ in ctants: @@ -206,8 +198,7 @@ def get_contest(id: int) -> db.Contest: def get_contest_rr(id: int, right_needed: Optional[Right] = None) -> Tuple[db.Contest, Rights]: contest = get_contest(id) - rr = Rights(g.user) - rr.get_for_contest(contest) + rr = g.gatekeeper.rights_for_contest(contest) if not (right_needed is None or rr.have_right(right_needed)): raise werkzeug.exceptions.Forbidden() @@ -215,7 +206,7 @@ def get_contest_rr(id: int, right_needed: Optional[Right] = None) -> Tuple[db.Co return contest, rr -def get_contest_site_rr(id: int, site_id: Optional[int], right_needed: Optional[Right] = None) -> Tuple[db.Contest, db.Place, Rights]: +def get_contest_site_rr(id: int, site_id: Optional[int], right_needed: Optional[Right] = None) -> Tuple[db.Contest, Optional[db.Place], Rights]: if site_id is None: contest, rr = get_contest_rr(id, right_needed) return contest, None, rr @@ -225,8 +216,7 @@ def get_contest_site_rr(id: int, site_id: Optional[int], right_needed: Optional[ if not site: raise werkzeug.exceptions.NotFound() - rr = Rights(g.user) - rr.get_for_contest_site(contest, site) + rr = g.gatekeeper.rights_for_contest_site(contest, site) if not (right_needed is None or rr.have_right(right_needed)): raise werkzeug.exceptions.Forbidden() @@ -274,7 +264,7 @@ def org_contest(id: int, site_id: Optional[int] = None): 'org_contest.html', contest=contest, site=site, db=db, # kvůli hodnotám enumů - rights=sorted(rr.current_rights, key=lambda r: r. name), + rights=sorted(rr.rights, key=lambda r: r. name), can_manage=rr.have_right(Right.manage_contest), can_edit_points=rr.have_right(Right.edit_points) and contest.round.state == db.RoundState.grading, tasks=tasks, places_counts=places_counts, @@ -355,7 +345,7 @@ def org_contest_list(id: int, site_id: Optional[int] = None): action_form = None if can_edit: action_form = ParticipantsActionForm() - if action_form.do_action(round=contest.round, rights=rr, query=query): + if action_form.do_action(round=contest.round, query=query): # Action happened, redirect return redirect(request.url) @@ -518,8 +508,7 @@ def get_solution_context(contest_id: int, user_id: Optional[int], task_id: Optio if not site: raise werkzeug.exceptions.NotFound() - rr = Rights(g.user) - rr.get_for_contest_site(contest, site or contest.place) + rr = g.gatekeeper.rights_for_contest_site(contest, site or contest.place) # Kdo má právo na jaké operace allow_upload_solutions = (rr.have_right(Right.upload_submits) diff --git a/mo/web/org_round.py b/mo/web/org_round.py index d157837449c5a0f01e71ee295304caad22f636e3..3780150f738f218ef912ce97bce355f2f5c80cb9 100644 --- a/mo/web/org_round.py +++ b/mo/web/org_round.py @@ -1,8 +1,6 @@ from typing import Optional, Tuple from flask import render_template, g, redirect, url_for, flash, request import locale -import os -import secrets from flask_wtf.form import FlaskForm from sqlalchemy import func from sqlalchemy.orm import joinedload @@ -14,7 +12,7 @@ from wtforms import validators import mo import mo.db as db import mo.imports -import mo.rights +from mo.rights import Right, Rights import mo.util from mo.web import app from mo.web.org_contest import ParticipantsActionForm, ParticipantsFilterForm, get_contestants_query, make_contestant_table, generic_import @@ -27,11 +25,10 @@ def get_round(id: int) -> db.Round: return round -def get_round_rr(id: int, right_needed: Optional[mo.rights.Right]) -> Tuple[db.Round, mo.rights.Rights]: +def get_round_rr(id: int, right_needed: Optional[Right]) -> Tuple[db.Round, Rights]: round = get_round(id) - rr = mo.rights.Rights(g.user) - rr.get_for_round(round) + rr = g.gatekeeper.rights_for_round(round) if not (right_needed is None or rr.have_right(right_needed)): raise werkzeug.exceptions.Forbidden() @@ -57,8 +54,8 @@ def org_round(id: int): sess = db.get_session() round, rr = get_round_rr(id, None) - can_manage_round = rr.have_right(mo.rights.Right.manage_round) - can_manage_contestants = rr.have_right(mo.rights.Right.manage_contest) + can_manage_round = rr.have_right(Right.manage_round) + can_manage_contestants = rr.have_right(Right.manage_contest) participants_count = sess.query( db.Participation.contest_id, @@ -136,7 +133,7 @@ class TaskEditForm(FlaskForm): @app.route('/org/contest/r/<int:id>/task/new', methods=('GET', 'POST')) def org_round_task_new(id: int): sess = db.get_session() - round, rr = get_round_rr(id, mo.rights.Right.manage_round) + round, rr = get_round_rr(id, Right.manage_round) form = TaskEditForm() if form.validate_on_submit(): @@ -168,7 +165,7 @@ def org_round_task_new(id: int): @app.route('/org/contest/r/<int:id>/task/<int:task_id>/edit', methods=('GET', 'POST')) def org_round_task_edit(id: int, task_id: int): sess = db.get_session() - round, rr = get_round_rr(id, mo.rights.Right.manage_round) + round, rr = get_round_rr(id, Right.manage_round) task = sess.query(db.Task).get(task_id) if not task: @@ -206,7 +203,7 @@ def org_round_task_edit(id: int, task_id: int): @app.route('/org/contest/r/<int:id>/list', methods=('GET', 'POST')) def org_round_list(id: int): - round, rr = get_round_rr(id, mo.rights.Right.manage_contest) + round, rr = get_round_rr(id, Right.manage_contest) format = request.args.get('format', "") filter = ParticipantsFilterForm(request.args) @@ -220,7 +217,7 @@ def org_round_list(id: int): ) action_form = ParticipantsActionForm() - if action_form.do_action(round=round, rights=rr, query=query): + if action_form.do_action(round=round, query=query): # Action happened, redirect return redirect(request.url) @@ -242,7 +239,7 @@ def org_round_list(id: int): @app.route('/org/contest/r/<int:id>/import', methods=('GET', 'POST')) def org_round_import(id: int): - round, rr = get_round_rr(id, mo.rights.Right.manage_contest) + round, rr = get_round_rr(id, Right.manage_contest) return generic_import(round, None) @@ -269,7 +266,7 @@ class RoundEditForm(FlaskForm): @app.route('/org/contest/r/<int:id>/edit', methods=('GET', 'POST')) def org_round_edit(id: int): sess = db.get_session() - round, rr = get_round_rr(id, mo.rights.Right.manage_round) + round, rr = get_round_rr(id, Right.manage_round) form = RoundEditForm(obj=round) if form.validate_on_submit():