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

Práva: Soutěže a kola

parent cdb70106
No related branches found
No related tags found
1 merge request!19Reforma vyhodnocování práv
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
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,17 +121,12 @@ 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
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'
......@@ -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)
......
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():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment