From d55b49afe66593ba7567669b6267061108a17287 Mon Sep 17 00:00:00 2001 From: Martin Mares <mj@ucw.cz> Date: Sat, 9 Jan 2021 17:09:47 +0100 Subject: [PATCH] =?UTF-8?q?Opravy=20vyhodnocov=C3=A1n=C3=AD=20pr=C3=A1v=20?= =?UTF-8?q?k=20=C5=99e=C5=A1en=C3=ADm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mo/web/org_contest.py | 55 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index c1a3836f..9f9bd888 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -451,13 +451,14 @@ class SolutionContext: contest: db.Contest round: db.Round pion: db.Participation - solution: db.Solution + task: db.Task + solution: Optional[db.Solution] allow_view: bool allow_upload_solutions: bool allow_upload_feedback: bool -def get_solution_context(contest_id, user_id, task_id) -> SolutionContext: +def get_solution_context(contest_id: int, site_id: Optional[int], user_id: int, task_id: int) -> SolutionContext: sess = db.get_session() # Nejprve zjistíme, zda existuje soutěž @@ -472,37 +473,36 @@ def get_solution_context(contest_id, user_id, task_id) -> SolutionContext: if not pion: raise werkzeug.exceptions.NotFound() - # Najdeme jeho řešení úlohy - sol = (sess.query(db.Solution) - .filter_by(user_id=user_id, task_id=task_id) - .options(joinedload(db.Solution.task)) - .one_or_none()) - if not sol: + # A zda soutěží na zadaném soutěžním místě, je-li určeno + if site_id is not None and site_id != pion.site_id: raise werkzeug.exceptions.NotFound() - # Zkontrolujeme, že úloha je součástí soutěže - if sol.round != round: + # Najdeme úlohu a ověříme, že je součástí soutěže + task = sess.query(db.Task).get(task_id) + if not task or task.round_id != round: raise werkzeug.exceptions.NotFound() - # Má uživatel práva skrz contest? - rr = Rights(g.user) - rr.get_for_contest(contest) - all_rights = rr.current_rights + # Najdeme řešení úlohy (nemusí existovat) + sol = (sess.query(db.Solution) + .filter_by(user_id=user_id, task_id=task_id) + .one_or_none()) - # Má práva skrz soutěžní místo? - if pion.place != contest.place: - rr.get_for_contest_site(contest, pion.place) - all_rights = all_rights | rr.current_rights + # Pokud je uvedeno soutěžní místo, hledáme práva k němu, jinak k soutěži + if site_id is not None: + site = pion.place + else: + site = contest.place + rr = Rights(g.user) + rr.get_for_contest_site(contest, site) # Kdo má právo na jaké operace - allow_upload_solutions = (Right.manage_contest in all_rights - or (Right.upload_solutions in all_rights and round.state == db.RoundState.running)) - allow_upload_feedback = (Right.manage_contest in all_rights - or (Right.upload_feedback in all_rights and round.state == db.RoundState.grading)) - allow_view = (Right.manage_contest in all_rights - or (Right.upload_solutions in all_rights and round.state != db.RoundState.preparing) - or (Right.upload_feedback in all_rights and round.state in (db.RoundState.preparing, db.RoundState.running, db.RoundState.closed))) - + allow_upload_solutions = (rr.have_right(Right.manage_contest) + or (rr.have_right(Right.upload_solutions) and round.state == db.RoundState.running)) + allow_upload_feedback = (rr.have_right(Right.manage_contest) + or (rr.have_right(Right.upload_feedback) and round.state == db.RoundState.grading)) + allow_view = (rr.have_right(Right.manage_contest) + or (rr.have_right(Right.upload_solutions) and round.state in (db.RoundState.running, db.RoundState.grading, db.RoundState.closed)) + or (rr.have_right(Right.upload_feedback) and round.state in (db.RoundState.grading, db.RoundState.closed))) if not allow_view: raise werkzeug.exceptions.Forbidden() @@ -510,6 +510,7 @@ def get_solution_context(contest_id, user_id, task_id) -> SolutionContext: contest=contest, round=round, pion=pion, + task=task, solution=sol, allow_view=allow_view, allow_upload_solutions=allow_upload_solutions, @@ -519,7 +520,7 @@ def get_solution_context(contest_id, user_id, task_id) -> SolutionContext: @app.route('/org/contest/c/<int:contest_id>/submit/<int:user_id>/<int:task_id>/') def org_submit_list(contest_id, user_id, task_id): - sc = get_solution_context(contest_id, user_id, task_id) + sc = get_solution_context(contest_id, None, user_id, task_id) # FIXME -- GitLab