Skip to content
Snippets Groups Projects
Commit 89844ead authored by Martin Mareš's avatar Martin Mareš
Browse files

Práva: Soutěže a kola

parent 45f1ee54
No related branches found
No related tags found
1 merge request!17Výsledkovka pomocí mo.web.table
This commit is part of merge request !19. Comments created here will be created in the context of that merge request.
...@@ -16,7 +16,6 @@ from mo.csv import FileFormat ...@@ -16,7 +16,6 @@ from mo.csv import FileFormat
import mo.db as db import mo.db as db
from mo.imports import ImportType, create_import from mo.imports import ImportType, create_import
import mo.jobs.submit import mo.jobs.submit
import mo.rights
from mo.rights import Right, Rights from mo.rights import Right, Rights
import mo.util import mo.util
from mo.util_format import inflect_number from mo.util_format import inflect_number
...@@ -78,11 +77,9 @@ class ParticipantsActionForm(FlaskForm): ...@@ -78,11 +77,9 @@ class ParticipantsActionForm(FlaskForm):
remove_participation = wtforms.SubmitField("Smazat záznam o účasti") 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 """Do participation modification on partipations from given query
(possibly filtered by checkboxes). `rights` param is used to check rights (possibly filtered by checkboxes)."""
for contest of each modified participation or for contest in which
participation is moved to."""
if not self.validate_on_submit(): if not self.validate_on_submit():
return False return False
...@@ -106,8 +103,8 @@ class ParticipantsActionForm(FlaskForm): ...@@ -106,8 +103,8 @@ class ParticipantsActionForm(FlaskForm):
if not contest: if not contest:
flash(f"Nepovedlo se najít soutěž v kole {round.round_code()} v oblasti {contest_place.name}", 'danger') flash(f"Nepovedlo se najít soutěž v kole {round.round_code()} v oblasti {contest_place.name}", 'danger')
return False return False
rights.get_for_contest(contest) rr = g.gatekeeper.rights_for_contest(contest)
if not rights.have_right(Right.manage_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') 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 return False
elif self.remove_participation.data: elif self.remove_participation.data:
...@@ -124,17 +121,12 @@ class ParticipantsActionForm(FlaskForm): ...@@ -124,17 +121,12 @@ class ParticipantsActionForm(FlaskForm):
# Check all participations if we can edit them # Check all participations if we can edit them
ctants = query.all() ctants = query.all()
rights_cache = set()
for pion, _, _ in ctants: for pion, _, _ in ctants:
u = pion.user u = pion.user
if self.action_on.data == 'checked' and u.user_id not in user_ids: if self.action_on.data == 'checked' and u.user_id not in user_ids:
continue continue
if pion.contest_id in rights_cache: rr = g.gatekeeper.rights_for_contest(pion.contest)
continue if not rr.have_right(Right.manage_contest):
rights.get_for_contest(pion.contest)
if rights.have_right(Right.manage_contest):
rights_cache.add(pion.contest_id)
continue
flash( flash(
f"Nemáte právo ke správě soutěže v kole {round.round_code()} v oblasti {pion.contest.place.name} " 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' + f"(účastník {u.full_name()}). Žádná akce nebyla provedena.", 'danger'
...@@ -206,8 +198,7 @@ def get_contest(id: int) -> db.Contest: ...@@ -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]: def get_contest_rr(id: int, right_needed: Optional[Right] = None) -> Tuple[db.Contest, Rights]:
contest = get_contest(id) contest = get_contest(id)
rr = Rights(g.user) rr = g.gatekeeper.rights_for_contest(contest)
rr.get_for_contest(contest)
if not (right_needed is None or rr.have_right(right_needed)): if not (right_needed is None or rr.have_right(right_needed)):
raise werkzeug.exceptions.Forbidden() raise werkzeug.exceptions.Forbidden()
...@@ -215,7 +206,7 @@ def get_contest_rr(id: int, right_needed: Optional[Right] = None) -> Tuple[db.Co ...@@ -215,7 +206,7 @@ def get_contest_rr(id: int, right_needed: Optional[Right] = None) -> Tuple[db.Co
return contest, rr 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: if site_id is None:
contest, rr = get_contest_rr(id, right_needed) contest, rr = get_contest_rr(id, right_needed)
return contest, None, rr return contest, None, rr
...@@ -225,8 +216,7 @@ def get_contest_site_rr(id: int, site_id: Optional[int], right_needed: Optional[ ...@@ -225,8 +216,7 @@ def get_contest_site_rr(id: int, site_id: Optional[int], right_needed: Optional[
if not site: if not site:
raise werkzeug.exceptions.NotFound() raise werkzeug.exceptions.NotFound()
rr = Rights(g.user) rr = g.gatekeeper.rights_for_contest_site(contest, site)
rr.get_for_contest_site(contest, site)
if not (right_needed is None or rr.have_right(right_needed)): if not (right_needed is None or rr.have_right(right_needed)):
raise werkzeug.exceptions.Forbidden() raise werkzeug.exceptions.Forbidden()
...@@ -274,7 +264,7 @@ def org_contest(id: int, site_id: Optional[int] = None): ...@@ -274,7 +264,7 @@ def org_contest(id: int, site_id: Optional[int] = None):
'org_contest.html', 'org_contest.html',
contest=contest, site=site, contest=contest, site=site,
db=db, # kvůli hodnotám enumů 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_manage=rr.have_right(Right.manage_contest),
can_edit_points=rr.have_right(Right.edit_points) and contest.round.state == db.RoundState.grading, can_edit_points=rr.have_right(Right.edit_points) and contest.round.state == db.RoundState.grading,
tasks=tasks, places_counts=places_counts, tasks=tasks, places_counts=places_counts,
...@@ -355,7 +345,7 @@ def org_contest_list(id: int, site_id: Optional[int] = None): ...@@ -355,7 +345,7 @@ def org_contest_list(id: int, site_id: Optional[int] = None):
action_form = None action_form = None
if can_edit: if can_edit:
action_form = ParticipantsActionForm() 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 # Action happened, redirect
return redirect(request.url) return redirect(request.url)
...@@ -518,8 +508,7 @@ def get_solution_context(contest_id: int, user_id: Optional[int], task_id: Optio ...@@ -518,8 +508,7 @@ def get_solution_context(contest_id: int, user_id: Optional[int], task_id: Optio
if not site: if not site:
raise werkzeug.exceptions.NotFound() raise werkzeug.exceptions.NotFound()
rr = Rights(g.user) rr = g.gatekeeper.rights_for_contest_site(contest, site or contest.place)
rr.get_for_contest_site(contest, site or contest.place)
# Kdo má právo na jaké operace # Kdo má právo na jaké operace
allow_upload_solutions = (rr.have_right(Right.upload_submits) allow_upload_solutions = (rr.have_right(Right.upload_submits)
......
from typing import Optional, Tuple from typing import Optional, Tuple
from flask import render_template, g, redirect, url_for, flash, request from flask import render_template, g, redirect, url_for, flash, request
import locale import locale
import os
import secrets
from flask_wtf.form import FlaskForm from flask_wtf.form import FlaskForm
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
...@@ -14,7 +12,7 @@ from wtforms import validators ...@@ -14,7 +12,7 @@ from wtforms import validators
import mo import mo
import mo.db as db import mo.db as db
import mo.imports import mo.imports
import mo.rights from mo.rights import Right, Rights
import mo.util import mo.util
from mo.web import app from mo.web import app
from mo.web.org_contest import ParticipantsActionForm, ParticipantsFilterForm, get_contestants_query, make_contestant_table, generic_import 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: ...@@ -27,11 +25,10 @@ def get_round(id: int) -> db.Round:
return 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) round = get_round(id)
rr = mo.rights.Rights(g.user) rr = g.gatekeeper.rights_for_round(round)
rr.get_for_round(round)
if not (right_needed is None or rr.have_right(right_needed)): if not (right_needed is None or rr.have_right(right_needed)):
raise werkzeug.exceptions.Forbidden() raise werkzeug.exceptions.Forbidden()
...@@ -57,8 +54,8 @@ def org_round(id: int): ...@@ -57,8 +54,8 @@ def org_round(id: int):
sess = db.get_session() sess = db.get_session()
round, rr = get_round_rr(id, None) round, rr = get_round_rr(id, None)
can_manage_round = rr.have_right(mo.rights.Right.manage_round) can_manage_round = rr.have_right(Right.manage_round)
can_manage_contestants = rr.have_right(mo.rights.Right.manage_contest) can_manage_contestants = rr.have_right(Right.manage_contest)
participants_count = sess.query( participants_count = sess.query(
db.Participation.contest_id, db.Participation.contest_id,
...@@ -136,7 +133,7 @@ class TaskEditForm(FlaskForm): ...@@ -136,7 +133,7 @@ class TaskEditForm(FlaskForm):
@app.route('/org/contest/r/<int:id>/task/new', methods=('GET', 'POST')) @app.route('/org/contest/r/<int:id>/task/new', methods=('GET', 'POST'))
def org_round_task_new(id: int): def org_round_task_new(id: int):
sess = db.get_session() 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() form = TaskEditForm()
if form.validate_on_submit(): if form.validate_on_submit():
...@@ -168,7 +165,7 @@ def org_round_task_new(id: int): ...@@ -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')) @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): def org_round_task_edit(id: int, task_id: int):
sess = db.get_session() 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) task = sess.query(db.Task).get(task_id)
if not task: if not task:
...@@ -206,7 +203,7 @@ def org_round_task_edit(id: int, task_id: int): ...@@ -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')) @app.route('/org/contest/r/<int:id>/list', methods=('GET', 'POST'))
def org_round_list(id: int): 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', "") format = request.args.get('format', "")
filter = ParticipantsFilterForm(request.args) filter = ParticipantsFilterForm(request.args)
...@@ -220,7 +217,7 @@ def org_round_list(id: int): ...@@ -220,7 +217,7 @@ def org_round_list(id: int):
) )
action_form = ParticipantsActionForm() 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 # Action happened, redirect
return redirect(request.url) return redirect(request.url)
...@@ -242,7 +239,7 @@ def org_round_list(id: int): ...@@ -242,7 +239,7 @@ def org_round_list(id: int):
@app.route('/org/contest/r/<int:id>/import', methods=('GET', 'POST')) @app.route('/org/contest/r/<int:id>/import', methods=('GET', 'POST'))
def org_round_import(id: int): 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) return generic_import(round, None)
...@@ -269,7 +266,7 @@ class RoundEditForm(FlaskForm): ...@@ -269,7 +266,7 @@ class RoundEditForm(FlaskForm):
@app.route('/org/contest/r/<int:id>/edit', methods=('GET', 'POST')) @app.route('/org/contest/r/<int:id>/edit', methods=('GET', 'POST'))
def org_round_edit(id: int): def org_round_edit(id: int):
sess = db.get_session() 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) form = RoundEditForm(obj=round)
if form.validate_on_submit(): if form.validate_on_submit():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment