Configuration: éditeur de rôles et permissions

This commit is contained in:
Emmanuel Viennet 2023-09-29 21:17:31 +02:00
parent db062d5b4a
commit 18263678c2
79 changed files with 910 additions and 561 deletions

View File

@ -451,7 +451,7 @@ def count_assiduites_formsemestre(
@scodoc @scodoc
@as_json @as_json
@login_required @login_required
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def assiduite_create(etudid: int = None, nip=None, ine=None): def assiduite_create(etudid: int = None, nip=None, ine=None):
""" """
Création d'une assiduité pour l'étudiant (etudid) Création d'une assiduité pour l'étudiant (etudid)
@ -506,7 +506,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None):
@scodoc @scodoc
@as_json @as_json
@login_required @login_required
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def assiduites_create(): def assiduites_create():
""" """
Création d'une assiduité ou plusieurs assiduites Création d'une assiduité ou plusieurs assiduites
@ -648,7 +648,7 @@ def _create_singular(
@login_required @login_required
@scodoc @scodoc
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def assiduite_delete(): def assiduite_delete():
""" """
Suppression d'une assiduité à partir de son id Suppression d'une assiduité à partir de son id
@ -700,7 +700,7 @@ def _delete_singular(assiduite_id: int, database):
@login_required @login_required
@scodoc @scodoc
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def assiduite_edit(assiduite_id: int): def assiduite_edit(assiduite_id: int):
""" """
Edition d'une assiduité à partir de son id Edition d'une assiduité à partir de son id
@ -740,7 +740,7 @@ def assiduite_edit(assiduite_id: int):
@login_required @login_required
@scodoc @scodoc
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def assiduites_edit(): def assiduites_edit():
""" """
Edition de plusieurs assiduités Edition de plusieurs assiduités

View File

@ -38,7 +38,7 @@ def billets_absence_etudiant(etudid: int):
@api_web_bp.route("/billets_absence/create", methods=["POST"]) @api_web_bp.route("/billets_absence/create", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoAbsAddBillet) @permission_required(Permission.AbsAddBillet)
@as_json @as_json
def billets_absence_create(): def billets_absence_create():
"""Ajout d'un billet d'absence""" """Ajout d'un billet d'absence"""
@ -70,7 +70,7 @@ def billets_absence_create():
@api_web_bp.route("/billets_absence/<int:billet_id>/delete", methods=["POST"]) @api_web_bp.route("/billets_absence/<int:billet_id>/delete", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoAbsAddBillet) @permission_required(Permission.AbsAddBillet)
@as_json @as_json
def billets_absence_delete(billet_id: int): def billets_absence_delete(billet_id: int):
"""Suppression d'un billet d'absence""" """Suppression d'un billet d'absence"""

View File

@ -178,11 +178,11 @@ def get_photo_image(etudid: int = None, nip: str = None, ine: str = None):
@api_web_bp.route("/etudiant/etudid/<int:etudid>/photo", methods=["POST"]) @api_web_bp.route("/etudiant/etudid/<int:etudid>/photo", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEtudChangeAdr) @permission_required(Permission.EtudChangeAdr)
@as_json @as_json
def set_photo_image(etudid: int = None): def set_photo_image(etudid: int = None):
"""Enregistre la photo de l'étudiant.""" """Enregistre la photo de l'étudiant."""
allowed_depts = current_user.get_depts_with_permission(Permission.ScoEtudChangeAdr) allowed_depts = current_user.get_depts_with_permission(Permission.EtudChangeAdr)
query = Identite.query.filter_by(id=etudid) query = Identite.query.filter_by(id=etudid)
if not None in allowed_depts: if not None in allowed_depts:
# restreint aux départements autorisés: # restreint aux départements autorisés:

View File

@ -146,7 +146,7 @@ def evaluation_notes(evaluation_id: int):
@api_web_bp.route("/evaluation/<int:evaluation_id>/notes/set", methods=["POST"]) @api_web_bp.route("/evaluation/<int:evaluation_id>/notes/set", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) @permission_required(Permission.EnsView)
@as_json @as_json
def evaluation_set_notes(evaluation_id: int): def evaluation_set_notes(evaluation_id: int):
"""Écriture de notes dans une évaluation. """Écriture de notes dans une évaluation.
@ -187,7 +187,7 @@ def evaluation_set_notes(evaluation_id: int):
@api_web_bp.route("/moduleimpl/<int:moduleimpl_id>/evaluation/create", methods=["POST"]) @api_web_bp.route("/moduleimpl/<int:moduleimpl_id>/evaluation/create", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) # permission gérée dans la fonction @permission_required(Permission.EnsView) # permission gérée dans la fonction
@as_json @as_json
def evaluation_create(moduleimpl_id: int): def evaluation_create(moduleimpl_id: int):
"""Création d'une évaluation. """Création d'une évaluation.
@ -251,7 +251,7 @@ def evaluation_create(moduleimpl_id: int):
@api_web_bp.route("/evaluation/<int:evaluation_id>/delete", methods=["POST"]) @api_web_bp.route("/evaluation/<int:evaluation_id>/delete", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) # permission gérée dans la fonction @permission_required(Permission.EnsView) # permission gérée dans la fonction
@as_json @as_json
def evaluation_delete(evaluation_id: int): def evaluation_delete(evaluation_id: int):
"""Suppression d'une évaluation. """Suppression d'une évaluation.

View File

@ -251,7 +251,7 @@ def referentiel_competences(formation_id: int):
@api_web_bp.route("/set_ue_parcours/<int:ue_id>", methods=["POST"]) @api_web_bp.route("/set_ue_parcours/<int:ue_id>", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
@as_json @as_json
def set_ue_parcours(ue_id: int): def set_ue_parcours(ue_id: int):
"""Associe UE et parcours BUT. """Associe UE et parcours BUT.
@ -286,7 +286,7 @@ def set_ue_parcours(ue_id: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
@as_json @as_json
def assoc_ue_niveau(ue_id: int, niveau_id: int): def assoc_ue_niveau(ue_id: int, niveau_id: int):
"""Associe l'UE au niveau de compétence""" """Associe l'UE au niveau de compétence"""
@ -315,7 +315,7 @@ def assoc_ue_niveau(ue_id: int, niveau_id: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
@as_json @as_json
def desassoc_ue_niveau(ue_id: int): def desassoc_ue_niveau(ue_id: int):
"""Désassocie cette UE de son niveau de compétence """Désassocie cette UE de son niveau de compétence

View File

@ -120,7 +120,7 @@ def _validation_ue_delete(etudid: int, validation_id: int):
# (c'est le cas pour les validations de jury, mais pas pour les "antérieures" non # (c'est le cas pour les validations de jury, mais pas pour les "antérieures" non
# rattachées à un formsemestre) # rattachées à un formsemestre)
if not g.scodoc_dept: # accès API if not g.scodoc_dept: # accès API
if not current_user.has_permission(Permission.ScoEtudInscrit): if not current_user.has_permission(Permission.EtudInscrit):
return json_error(403, "opération non autorisée (117)") return json_error(403, "opération non autorisée (117)")
else: else:
if validation.formsemestre: if validation.formsemestre:
@ -128,7 +128,7 @@ def _validation_ue_delete(etudid: int, validation_id: int):
validation.formsemestre.dept_id != g.scodoc_dept_id validation.formsemestre.dept_id != g.scodoc_dept_id
) or not validation.formsemestre.can_edit_jury(): ) or not validation.formsemestre.can_edit_jury():
return json_error(403, "opération non autorisée (123)") return json_error(403, "opération non autorisée (123)")
elif not current_user.has_permission(Permission.ScoEtudInscrit): elif not current_user.has_permission(Permission.EtudInscrit):
# Validation non rattachée à un semestre: on doit être chef # Validation non rattachée à un semestre: on doit être chef
return json_error(403, "opération non autorisée (126)") return json_error(403, "opération non autorisée (126)")
@ -150,7 +150,7 @@ def _validation_ue_delete(etudid: int, validation_id: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@as_json @as_json
def autorisation_inscription_delete(etudid: int, validation_id: int): def autorisation_inscription_delete(etudid: int, validation_id: int):
"Efface cette validation" "Efface cette validation"
@ -178,7 +178,7 @@ def autorisation_inscription_delete(etudid: int, validation_id: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@as_json @as_json
def validation_rcue_record(etudid: int): def validation_rcue_record(etudid: int):
"""Enregistre une validation de RCUE. """Enregistre une validation de RCUE.
@ -305,7 +305,7 @@ def validation_rcue_record(etudid: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@as_json @as_json
def validation_rcue_delete(etudid: int, validation_id: int): def validation_rcue_delete(etudid: int, validation_id: int):
"Efface cette validation" "Efface cette validation"
@ -333,7 +333,7 @@ def validation_rcue_delete(etudid: int, validation_id: int):
) )
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@as_json @as_json
def validation_annee_but_delete(etudid: int, validation_id: int): def validation_annee_but_delete(etudid: int, validation_id: int):
"Efface cette validation" "Efface cette validation"

View File

@ -241,7 +241,7 @@ def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False):
@scodoc @scodoc
@login_required @login_required
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_create(etudid: int = None, nip=None, ine=None): def justif_create(etudid: int = None, nip=None, ine=None):
""" """
Création d'un justificatif pour l'étudiant (etudid) Création d'un justificatif pour l'étudiant (etudid)
@ -372,7 +372,7 @@ def _create_singular(
@login_required @login_required
@scodoc @scodoc
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_edit(justif_id: int): def justif_edit(justif_id: int):
""" """
Edition d'un justificatif à partir de son id Edition d'un justificatif à partir de son id
@ -471,7 +471,7 @@ def justif_edit(justif_id: int):
@login_required @login_required
@scodoc @scodoc
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_delete(): def justif_delete():
""" """
Suppression d'un justificatif à partir de son id Suppression d'un justificatif à partir de son id
@ -534,7 +534,7 @@ def _delete_singular(justif_id: int, database):
@scodoc @scodoc
@login_required @login_required
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_import(justif_id: int = None): def justif_import(justif_id: int = None):
""" """
Importation d'un fichier (création d'archive) Importation d'un fichier (création d'archive)
@ -579,7 +579,7 @@ def justif_import(justif_id: int = None):
@api_web_bp.route("/justificatif/<int:justif_id>/export/<filename>", methods=["POST"]) @api_web_bp.route("/justificatif/<int:justif_id>/export/<filename>", methods=["POST"])
@scodoc @scodoc
@login_required @login_required
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_export(justif_id: int = None, filename: str = None): def justif_export(justif_id: int = None, filename: str = None):
""" """
Retourne un fichier d'une archive d'un justificatif Retourne un fichier d'une archive d'un justificatif
@ -610,7 +610,7 @@ def justif_export(justif_id: int = None, filename: str = None):
@scodoc @scodoc
@login_required @login_required
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_remove(justif_id: int = None): def justif_remove(justif_id: int = None):
""" """
Supression d'un fichier ou d'une archive Supression d'un fichier ou d'une archive
@ -700,7 +700,7 @@ def justif_list(justif_id: int = None):
for filename in filenames: for filename in filenames:
if int(filename[1]) == current_user.id or current_user.has_permission( if int(filename[1]) == current_user.id or current_user.has_permission(
Permission.ScoJustifView Permission.AbsJustifView
): ):
retour["filenames"].append(filename[0]) retour["filenames"].append(filename[0])
return retour return retour
@ -712,7 +712,7 @@ def justif_list(justif_id: int = None):
@scodoc @scodoc
@login_required @login_required
@as_json @as_json
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def justif_justifies(justif_id: int = None): def justif_justifies(justif_id: int = None):
""" """
Liste assiduite_id justifiées par le justificatif Liste assiduite_id justifiées par le justificatif

View File

@ -23,7 +23,7 @@
# @api_web_bp.route("/semset/set_periode/<int:semset_id>", methods=["POST"]) # @api_web_bp.route("/semset/set_periode/<int:semset_id>", methods=["POST"])
# @login_required # @login_required
# @scodoc # @scodoc
# @permission_required(Permission.ScoEditApo) # @permission_required(Permission.EditApogee)
# # TODO à modifier pour utiliser @as_json # # TODO à modifier pour utiliser @as_json
# def semset_set_periode(semset_id: int): # def semset_set_periode(semset_id: int):
# "Change la période d'un semset" # "Change la période d'un semset"

View File

@ -13,7 +13,7 @@ from flask import g, request
from flask_json import as_json from flask_json import as_json
from flask_login import current_user, login_required from flask_login import current_user, login_required
from app import db from app import db, log
from app.api import api_bp as bp, api_web_bp, API_CLIENT_ERROR from app.api import api_bp as bp, api_web_bp, API_CLIENT_ERROR
from app.scodoc.sco_utils import json_error from app.scodoc.sco_utils import json_error
from app.auth.models import User, Role, UserRole from app.auth.models import User, Role, UserRole
@ -29,7 +29,7 @@ from app.scodoc import sco_utils as scu
@api_web_bp.route("/user/<int:uid>") @api_web_bp.route("/user/<int:uid>")
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def user_info(uid: int): def user_info(uid: int):
""" """
@ -39,7 +39,7 @@ def user_info(uid: int):
if user is None: if user is None:
return json_error(404, "user not found") return json_error(404, "user not found")
if g.scodoc_dept: if g.scodoc_dept:
allowed_depts = current_user.get_depts_with_permission(Permission.ScoUsersView) allowed_depts = current_user.get_depts_with_permission(Permission.UsersView)
if (None not in allowed_depts) and (user.dept not in allowed_depts): if (None not in allowed_depts) and (user.dept not in allowed_depts):
return json_error(404, "user not found") return json_error(404, "user not found")
@ -78,7 +78,7 @@ def users_info_query():
query.join(UserRole, (UserRole.dept == User.dept) | (UserRole.dept == None)) query.join(UserRole, (UserRole.dept == User.dept) | (UserRole.dept == None))
.filter(UserRole.user == current_user) .filter(UserRole.user == current_user)
.join(Role, UserRole.role_id == Role.id) .join(Role, UserRole.role_id == Role.id)
.filter(Role.permissions.op("&")(Permission.ScoUsersView) != 0) .filter(Role.permissions.op("&")(Permission.UsersView) != 0)
) )
query = query.order_by(User.user_name) query = query.order_by(User.user_name)
@ -89,7 +89,7 @@ def users_info_query():
@api_web_bp.route("/user/create", methods=["POST"]) @api_web_bp.route("/user/create", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@as_json @as_json
def user_create(): def user_create():
"""Création d'un utilisateur """Création d'un utilisateur
@ -112,7 +112,7 @@ def user_create():
dept = data.get("dept") dept = data.get("dept")
if dept == "@all": if dept == "@all":
dept = None dept = None
allowed_depts = current_user.get_depts_with_permission(Permission.ScoUsersAdmin) allowed_depts = current_user.get_depts_with_permission(Permission.UsersAdmin)
if (None not in allowed_depts) and (dept not in allowed_depts): if (None not in allowed_depts) and (dept not in allowed_depts):
return json_error(403, "user_create: departement non autorise") return json_error(403, "user_create: departement non autorise")
if (dept is not None) and ( if (dept is not None) and (
@ -132,7 +132,7 @@ def user_create():
@api_web_bp.route("/user/<int:uid>/edit", methods=["POST"]) @api_web_bp.route("/user/<int:uid>/edit", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@as_json @as_json
def user_edit(uid: int): def user_edit(uid: int):
"""Modification d'un utilisateur """Modification d'un utilisateur
@ -152,7 +152,7 @@ def user_edit(uid: int):
if dest_dept is not False: if dest_dept is not False:
if dest_dept == "@all": if dest_dept == "@all":
dest_dept = None dest_dept = None
allowed_depts = current_user.get_depts_with_permission(Permission.ScoUsersAdmin) allowed_depts = current_user.get_depts_with_permission(Permission.UsersAdmin)
if (None not in allowed_depts) and ( if (None not in allowed_depts) and (
(orig_dept not in allowed_depts) or (dest_dept not in allowed_depts) (orig_dept not in allowed_depts) or (dest_dept not in allowed_depts)
): ):
@ -177,7 +177,7 @@ def user_edit(uid: int):
@api_web_bp.route("/user/<int:uid>/password", methods=["POST"]) @api_web_bp.route("/user/<int:uid>/password", methods=["POST"])
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@as_json @as_json
def user_password(uid: int): def user_password(uid: int):
"""Modification du mot de passe d'un utilisateur """Modification du mot de passe d'un utilisateur
@ -194,7 +194,7 @@ def user_password(uid: int):
return json_error(404, "user_password: missing password") return json_error(404, "user_password: missing password")
if not is_valid_password(password): if not is_valid_password(password):
return json_error(API_CLIENT_ERROR, "user_password: invalid password") return json_error(API_CLIENT_ERROR, "user_password: invalid password")
allowed_depts = current_user.get_depts_with_permission(Permission.ScoUsersAdmin) allowed_depts = current_user.get_depts_with_permission(Permission.UsersAdmin)
if (None not in allowed_depts) and ((user.dept not in allowed_depts)): if (None not in allowed_depts) and ((user.dept not in allowed_depts)):
return json_error(403, "user_password: departement non autorise") return json_error(403, "user_password: departement non autorise")
user.set_password(password) user.set_password(password)
@ -271,7 +271,7 @@ def user_role_remove(uid: int, role_name: str, dept: str = None):
@api_web_bp.route("/permissions") @api_web_bp.route("/permissions")
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def list_permissions(): def list_permissions():
"""Liste des noms de permissions définies""" """Liste des noms de permissions définies"""
@ -282,7 +282,7 @@ def list_permissions():
@api_web_bp.route("/role/<string:role_name>") @api_web_bp.route("/role/<string:role_name>")
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def list_role(role_name: str): def list_role(role_name: str):
"""Un rôle""" """Un rôle"""
@ -293,7 +293,7 @@ def list_role(role_name: str):
@api_web_bp.route("/roles") @api_web_bp.route("/roles")
@login_required @login_required
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def list_roles(): def list_roles():
"""Tous les rôles définis""" """Tous les rôles définis"""
@ -321,6 +321,7 @@ def role_permission_add(role_name: str, perm_name: str):
role.add_permission(permission) role.add_permission(permission)
db.session.add(role) db.session.add(role)
db.session.commit() db.session.commit()
log(f"role_permission_add({role_name}, {perm_name})")
return role.to_dict() return role.to_dict()
@ -345,6 +346,7 @@ def role_permission_remove(role_name: str, perm_name: str):
role.remove_permission(permission) role.remove_permission(permission)
db.session.add(role) db.session.add(role)
db.session.commit() db.session.commit()
log(f"role_permission_remove({role_name}, {perm_name})")
return role.to_dict() return role.to_dict()

View File

@ -541,6 +541,10 @@ class Role(db.Model):
"Remove all permissions from role" "Remove all permissions from role"
self.permissions = 0 self.permissions = 0
def get_named_permissions(self) -> list[str]:
"List of the names of the permissions associated to this rôle"
return Permission.permissions_names(self.permissions)
def set_named_permissions(self, permission_names: list[str]): def set_named_permissions(self, permission_names: list[str]):
"""Set permissions, given as a list of permissions names. """Set permissions, given as a list of permissions names.
Raises ScoValueError if invalid permission.""" Raises ScoValueError if invalid permission."""

View File

@ -21,7 +21,9 @@ from app.auth.forms import (
from app.auth.models import Role, User, invalid_user_name from app.auth.models import Role, User, invalid_user_name
from app.auth.email import send_password_reset_email from app.auth.email import send_password_reset_email
from app.decorators import admin_required from app.decorators import admin_required
from app.forms.generic import SimpleConfirmationForm
from app.models.config import ScoDocSiteConfig from app.models.config import ScoDocSiteConfig
from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
_ = lambda x: x # sans babel _ = lambda x: x # sans babel
@ -158,9 +160,25 @@ def reset_password(token):
@admin_required @admin_required
def reset_standard_roles_permissions(): def reset_standard_roles_permissions():
"Réinitialise (recrée au besoin) les rôles standards de ScoDoc et leurs permissions" "Réinitialise (recrée au besoin) les rôles standards de ScoDoc et leurs permissions"
Role.reset_standard_roles_permissions() form = SimpleConfirmationForm()
flash("rôles standards réinitialisés !") if request.method == "POST" and form.cancel.data:
return redirect(url_for("scodoc.configuration")) return redirect(url_for("scodoc.configuration"))
if form.validate_on_submit():
Role.reset_standard_roles_permissions()
flash("rôles standards réinitialisés !")
return redirect(url_for("scodoc.configuration"))
return render_template(
"form_confirmation.j2",
title="Réinitialiser les roles standards de ScoDoc ?",
form=form,
info_message=f"""<p>Les rôles standards seront recréés et leurs permissions
réinitialisées aux valeurs par défaut de ScoDoc.
</p>
<p>
Les rôles standards sont: <tt>{', '.join(SCO_ROLES_DEFAULTS.keys())}</tt>
</p>
""",
)
@bp.route("/cas_users_generate_excel_sample") @bp.route("/cas_users_generate_excel_sample")

View File

@ -131,7 +131,7 @@ def check_offre_depts(depts: list, offre_depts: list):
""" """
Retourne vrai si l'utilisateur a le droit de visibilité sur l'offre Retourne vrai si l'utilisateur a le droit de visibilité sur l'offre
""" """
if current_user.has_permission(Permission.RelationsEntreprisesChange, None): if current_user.has_permission(Permission.RelationsEntrepEdit, None):
return True return True
for offre_dept in offre_depts: for offre_dept in offre_depts:
if offre_dept.dept_id in depts: if offre_dept.dept_id in depts:

View File

@ -62,7 +62,7 @@ from config import Config
@bp.route("/", methods=["GET", "POST"]) @bp.route("/", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def index(): def index():
""" """
Permet d'afficher une page avec la liste des entreprises (visible et active) et une liste des dernières opérations Permet d'afficher une page avec la liste des entreprises (visible et active) et une liste des dernières opérations
@ -98,7 +98,7 @@ def index():
@bp.route("/logs", methods=["GET"]) @bp.route("/logs", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def logs(): def logs():
""" """
Permet d'afficher les logs (toutes les entreprises) Permet d'afficher les logs (toutes les entreprises)
@ -115,7 +115,7 @@ def logs():
@bp.route("/correspondants", methods=["GET"]) @bp.route("/correspondants", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesCorrespondants) @permission_required(Permission.RelationsEntrepViewCorrs)
def correspondants(): def correspondants():
""" """
Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations
@ -141,7 +141,7 @@ def correspondants():
@bp.route("/validation", methods=["GET"]) @bp.route("/validation", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesValidate) @permission_required(Permission.RelationsEntrepValidate)
def validation(): def validation():
""" """
Permet d'afficher une page avec la liste des entreprises a valider (non visible) Permet d'afficher une page avec la liste des entreprises a valider (non visible)
@ -155,7 +155,7 @@ def validation():
@bp.route("/fiche_entreprise_validation/<int:entreprise_id>", methods=["GET"]) @bp.route("/fiche_entreprise_validation/<int:entreprise_id>", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesValidate) @permission_required(Permission.RelationsEntrepValidate)
def fiche_entreprise_validation(entreprise_id): def fiche_entreprise_validation(entreprise_id):
""" """
Permet d'afficher la fiche entreprise d'une entreprise a valider Permet d'afficher la fiche entreprise d'une entreprise a valider
@ -176,7 +176,7 @@ def fiche_entreprise_validation(entreprise_id):
"/fiche_entreprise_validation/<int:entreprise_id>/validate_entreprise", "/fiche_entreprise_validation/<int:entreprise_id>/validate_entreprise",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesValidate) @permission_required(Permission.RelationsEntrepValidate)
def validate_entreprise(entreprise_id): def validate_entreprise(entreprise_id):
""" """
Permet de valider une entreprise Permet de valider une entreprise
@ -214,7 +214,7 @@ def validate_entreprise(entreprise_id):
"/fiche_entreprise_validation/<int:entreprise_id>/delete_validation_entreprise", "/fiche_entreprise_validation/<int:entreprise_id>/delete_validation_entreprise",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesValidate) @permission_required(Permission.RelationsEntrepValidate)
def delete_validation_entreprise(entreprise_id): def delete_validation_entreprise(entreprise_id):
""" """
Permet de supprimer une entreprise en attente de validation avec une formulaire de validation Permet de supprimer une entreprise en attente de validation avec une formulaire de validation
@ -241,7 +241,7 @@ def delete_validation_entreprise(entreprise_id):
flash("L'entreprise a été supprimée de la liste des entreprises à valider.") flash("L'entreprise a été supprimée de la liste des entreprises à valider.")
return redirect(url_for("entreprises.validation")) return redirect(url_for("entreprises.validation"))
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supression entreprise", title="Supression entreprise",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -249,7 +249,7 @@ def delete_validation_entreprise(entreprise_id):
@bp.route("/offres_recues", methods=["GET"]) @bp.route("/offres_recues", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def offres_recues(): def offres_recues():
""" """
Permet d'afficher la page où l'on peut voir les offres reçues Permet d'afficher la page où l'on peut voir les offres reçues
@ -290,7 +290,7 @@ def offres_recues():
@bp.route( @bp.route(
"/offres_recues/delete_offre_recue/<int:envoi_offre_id>", methods=["GET", "POST"] "/offres_recues/delete_offre_recue/<int:envoi_offre_id>", methods=["GET", "POST"]
) )
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def delete_offre_recue(envoi_offre_id): def delete_offre_recue(envoi_offre_id):
""" """
Permet de supprimer une offre reçue Permet de supprimer une offre reçue
@ -304,7 +304,7 @@ def delete_offre_recue(envoi_offre_id):
@bp.route("/preferences", methods=["GET", "POST"]) @bp.route("/preferences", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesValidate) @permission_required(Permission.RelationsEntrepValidate)
def preferences(): def preferences():
""" """
Permet d'afficher la page des préférences du module gestion des relations entreprises Permet d'afficher la page des préférences du module gestion des relations entreprises
@ -327,7 +327,7 @@ def preferences():
@bp.route("/add_entreprise", methods=["GET", "POST"]) @bp.route("/add_entreprise", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_entreprise(): def add_entreprise():
""" """
Permet d'ajouter une entreprise dans la base avec un formulaire Permet d'ajouter une entreprise dans la base avec un formulaire
@ -385,7 +385,7 @@ def add_entreprise():
notes=form.notes.data.strip(), notes=form.notes.data.strip(),
) )
db.session.add(correspondant) db.session.add(correspondant)
if current_user.has_permission(Permission.RelationsEntreprisesValidate, None): if current_user.has_permission(Permission.RelationsEntrepValidate, None):
entreprise.visible = True entreprise.visible = True
lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>" lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>"
log = EntrepriseHistorique( log = EntrepriseHistorique(
@ -414,7 +414,7 @@ def add_entreprise():
@bp.route("/fiche_entreprise/<int:entreprise_id>", methods=["GET"]) @bp.route("/fiche_entreprise/<int:entreprise_id>", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def fiche_entreprise(entreprise_id): def fiche_entreprise(entreprise_id):
""" """
Permet d'afficher la fiche entreprise d'une entreprise avec une liste des dernières opérations et Permet d'afficher la fiche entreprise d'une entreprise avec une liste des dernières opérations et
@ -456,7 +456,7 @@ def fiche_entreprise(entreprise_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/logs", methods=["GET"]) @bp.route("/fiche_entreprise/<int:entreprise_id>/logs", methods=["GET"])
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def logs_entreprise(entreprise_id): def logs_entreprise(entreprise_id):
""" """
Permet d'afficher les logs d'une entreprise Permet d'afficher les logs d'une entreprise
@ -479,7 +479,7 @@ def logs_entreprise(entreprise_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/offres_expirees") @bp.route("/fiche_entreprise/<int:entreprise_id>/offres_expirees")
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def offres_expirees(entreprise_id): def offres_expirees(entreprise_id):
""" """
Permet d'afficher la liste des offres expirés d'une entreprise Permet d'afficher la liste des offres expirés d'une entreprise
@ -499,7 +499,7 @@ def offres_expirees(entreprise_id):
@bp.route( @bp.route(
"/fiche_entreprise/<int:entreprise_id>/edit_entreprise", methods=["GET", "POST"] "/fiche_entreprise/<int:entreprise_id>/edit_entreprise", methods=["GET", "POST"]
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def edit_entreprise(entreprise_id): def edit_entreprise(entreprise_id):
""" """
Permet de modifier une entreprise de la base avec un formulaire Permet de modifier une entreprise de la base avec un formulaire
@ -580,7 +580,7 @@ def edit_entreprise(entreprise_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/desactiver", methods=["GET", "POST"]) @bp.route("/fiche_entreprise/<int:entreprise_id>/desactiver", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def fiche_entreprise_desactiver(entreprise_id): def fiche_entreprise_desactiver(entreprise_id):
""" """
Permet de désactiver une entreprise Permet de désactiver une entreprise
@ -609,7 +609,7 @@ def fiche_entreprise_desactiver(entreprise_id):
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id) url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Désactiver entreprise", title="Désactiver entreprise",
form=form, form=form,
info_message="Cliquez sur le bouton Modifier pour confirmer la désactivation", info_message="Cliquez sur le bouton Modifier pour confirmer la désactivation",
@ -617,7 +617,7 @@ def fiche_entreprise_desactiver(entreprise_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/activer", methods=["GET", "POST"]) @bp.route("/fiche_entreprise/<int:entreprise_id>/activer", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def fiche_entreprise_activer(entreprise_id): def fiche_entreprise_activer(entreprise_id):
""" """
Permet d'activer une entreprise Permet d'activer une entreprise
@ -645,7 +645,7 @@ def fiche_entreprise_activer(entreprise_id):
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id) url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Activer entreprise", title="Activer entreprise",
form=form, form=form,
info_message="Cliquez sur le bouton Modifier pour confirmer l'activaction", info_message="Cliquez sur le bouton Modifier pour confirmer l'activaction",
@ -774,7 +774,7 @@ def delete_taxe_apprentissage(entreprise_id, taxe_id):
url_for("entreprises.fiche_entreprise", entreprise_id=taxe.entreprise_id) url_for("entreprises.fiche_entreprise", entreprise_id=taxe.entreprise_id)
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supprimer taxe apprentissage", title="Supprimer taxe apprentissage",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -782,7 +782,7 @@ def delete_taxe_apprentissage(entreprise_id, taxe_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/add_offre", methods=["GET", "POST"]) @bp.route("/fiche_entreprise/<int:entreprise_id>/add_offre", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_offre(entreprise_id): def add_offre(entreprise_id):
""" """
Permet d'ajouter une offre a une entreprise Permet d'ajouter une offre a une entreprise
@ -854,7 +854,7 @@ def add_offre(entreprise_id):
"/fiche_entreprise/<int:entreprise_id>/edit_offre/<int:offre_id>", "/fiche_entreprise/<int:entreprise_id>/edit_offre/<int:offre_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def edit_offre(entreprise_id, offre_id): def edit_offre(entreprise_id, offre_id):
""" """
Permet de modifier une offre Permet de modifier une offre
@ -930,7 +930,7 @@ def edit_offre(entreprise_id, offre_id):
"/fiche_entreprise/<int:entreprise_id>/delete_offre/<int:offre_id>", "/fiche_entreprise/<int:entreprise_id>/delete_offre/<int:offre_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def delete_offre(entreprise_id, offre_id): def delete_offre(entreprise_id, offre_id):
""" """
Permet de supprimer une offre Permet de supprimer une offre
@ -970,7 +970,7 @@ def delete_offre(entreprise_id, offre_id):
url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id) url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supression offre", title="Supression offre",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -981,7 +981,7 @@ def delete_offre(entreprise_id, offre_id):
"/fiche_entreprise/<int:entreprise_id>/expired/<int:offre_id>", "/fiche_entreprise/<int:entreprise_id>/expired/<int:offre_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def expired(entreprise_id, offre_id): def expired(entreprise_id, offre_id):
""" """
Permet de rendre expirée et non expirée une offre Permet de rendre expirée et non expirée une offre
@ -1006,7 +1006,7 @@ def expired(entreprise_id, offre_id):
"/fiche_entreprise/<int:entreprise_id>/add_site", "/fiche_entreprise/<int:entreprise_id>/add_site",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_site(entreprise_id): def add_site(entreprise_id):
""" """
Permet d'ajouter un site a une entreprise Permet d'ajouter un site a une entreprise
@ -1107,7 +1107,7 @@ def edit_site(entreprise_id, site_id):
"/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/add_correspondant", "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/add_correspondant",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_correspondant(entreprise_id, site_id): def add_correspondant(entreprise_id, site_id):
""" """
Permet d'ajouter un correspondant a une entreprise Permet d'ajouter un correspondant a une entreprise
@ -1163,7 +1163,7 @@ def add_correspondant(entreprise_id, site_id):
"/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/edit_correspondant/<int:correspondant_id>", "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/edit_correspondant/<int:correspondant_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def edit_correspondant(entreprise_id, site_id, correspondant_id): def edit_correspondant(entreprise_id, site_id, correspondant_id):
""" """
Permet de modifier un correspondant Permet de modifier un correspondant
@ -1243,7 +1243,7 @@ def edit_correspondant(entreprise_id, site_id, correspondant_id):
"/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/delete_correspondant/<int:correspondant_id>", "/fiche_entreprise/<int:entreprise_id>/site/<int:site_id>/delete_correspondant/<int:correspondant_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def delete_correspondant(entreprise_id, site_id, correspondant_id): def delete_correspondant(entreprise_id, site_id, correspondant_id):
""" """
Permet de supprimer un correspondant Permet de supprimer un correspondant
@ -1289,7 +1289,7 @@ def delete_correspondant(entreprise_id, site_id, correspondant_id):
) )
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supression correspondant", title="Supression correspondant",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -1297,7 +1297,7 @@ def delete_correspondant(entreprise_id, site_id, correspondant_id):
@bp.route("/fiche_entreprise/<int:entreprise_id>/contacts") @bp.route("/fiche_entreprise/<int:entreprise_id>/contacts")
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def contacts(entreprise_id): def contacts(entreprise_id):
""" """
Permet d'afficher une page avec la liste des contacts d'une entreprise Permet d'afficher une page avec la liste des contacts d'une entreprise
@ -1318,7 +1318,7 @@ def contacts(entreprise_id):
"/fiche_entreprise/<int:entreprise_id>/contacts/add_contact", "/fiche_entreprise/<int:entreprise_id>/contacts/add_contact",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_contact(entreprise_id): def add_contact(entreprise_id):
""" """
Permet d'ajouter un contact avec une entreprise Permet d'ajouter un contact avec une entreprise
@ -1374,7 +1374,7 @@ def add_contact(entreprise_id):
"/fiche_entreprise/<int:entreprise_id>/contacts/edit_contact/<int:contact_id>", "/fiche_entreprise/<int:entreprise_id>/contacts/edit_contact/<int:contact_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def edit_contact(entreprise_id, contact_id): def edit_contact(entreprise_id, contact_id):
""" """
Permet d'editer un contact avec une entreprise Permet d'editer un contact avec une entreprise
@ -1430,7 +1430,7 @@ def edit_contact(entreprise_id, contact_id):
"/fiche_entreprise/<int:entreprise_id>/contacts/delete_contact/<int:contact_id>", "/fiche_entreprise/<int:entreprise_id>/contacts/delete_contact/<int:contact_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def delete_contact(entreprise_id, contact_id): def delete_contact(entreprise_id, contact_id):
""" """
Permet de supprimer un contact Permet de supprimer un contact
@ -1458,7 +1458,7 @@ def delete_contact(entreprise_id, contact_id):
url_for("entreprises.contacts", entreprise_id=contact.entreprise) url_for("entreprises.contacts", entreprise_id=contact.entreprise)
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supression contact", title="Supression contact",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -1469,7 +1469,7 @@ def delete_contact(entreprise_id, contact_id):
"/fiche_entreprise/<int:entreprise_id>/add_stage_apprentissage", "/fiche_entreprise/<int:entreprise_id>/add_stage_apprentissage",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_stage_apprentissage(entreprise_id): def add_stage_apprentissage(entreprise_id):
""" """
Permet d'ajouter un étudiant ayant réalisé un stage ou alternance Permet d'ajouter un étudiant ayant réalisé un stage ou alternance
@ -1528,7 +1528,7 @@ def add_stage_apprentissage(entreprise_id):
"/fiche_entreprise/<int:entreprise_id>/edit_stage_apprentissage/<int:stage_apprentissage_id>", "/fiche_entreprise/<int:entreprise_id>/edit_stage_apprentissage/<int:stage_apprentissage_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def edit_stage_apprentissage(entreprise_id, stage_apprentissage_id): def edit_stage_apprentissage(entreprise_id, stage_apprentissage_id):
""" """
Permet de modifier un étudiant ayant réalisé un stage ou alternance sur la fiche de l'entreprise Permet de modifier un étudiant ayant réalisé un stage ou alternance sur la fiche de l'entreprise
@ -1598,7 +1598,7 @@ def edit_stage_apprentissage(entreprise_id, stage_apprentissage_id):
"/fiche_entreprise/<int:entreprise_id>/delete_stage_apprentissage/<int:stage_apprentissage_id>", "/fiche_entreprise/<int:entreprise_id>/delete_stage_apprentissage/<int:stage_apprentissage_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id): def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id):
""" """
Permet de supprimer un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise Permet de supprimer un étudiant ayant réalisé un stage ou une alternance sur la fiche entreprise de l'entreprise
@ -1629,7 +1629,7 @@ def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id):
) )
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Supression stage/apprentissage", title="Supression stage/apprentissage",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
@ -1640,7 +1640,7 @@ def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id):
"/fiche_entreprise/<int:entreprise_id>/envoyer_offre/<int:offre_id>", "/fiche_entreprise/<int:entreprise_id>/envoyer_offre/<int:offre_id>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesSend) @permission_required(Permission.RelationsEntrepSend)
def envoyer_offre(entreprise_id, offre_id): def envoyer_offre(entreprise_id, offre_id):
""" """
Permet d'envoyer une offre à un utilisateur ScoDoc Permet d'envoyer une offre à un utilisateur ScoDoc
@ -1686,7 +1686,7 @@ def envoyer_offre(entreprise_id, offre_id):
@bp.route("/etudiants") @bp.route("/etudiants")
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
@as_json @as_json
def json_etudiants(): def json_etudiants():
""" """
@ -1717,7 +1717,7 @@ def json_etudiants():
@bp.route("/responsables") @bp.route("/responsables")
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def json_responsables(): def json_responsables():
""" """
Permet de récuperer un JSON avec tous les utilisateurs ScoDoc Permet de récuperer un JSON avec tous les utilisateurs ScoDoc
@ -1743,7 +1743,7 @@ def json_responsables():
@bp.route("/export_donnees") @bp.route("/export_donnees")
@permission_required(Permission.RelationsEntreprisesExport) @permission_required(Permission.RelationsEntrepExport)
def export_donnees(): def export_donnees():
""" """
Permet d'exporter la liste des entreprises sous format excel (.xlsx) Permet d'exporter la liste des entreprises sous format excel (.xlsx)
@ -1759,7 +1759,7 @@ def export_donnees():
@bp.route("/import_donnees/get_file_sample") @bp.route("/import_donnees/get_file_sample")
@permission_required(Permission.RelationsEntreprisesExport) @permission_required(Permission.RelationsEntrepExport)
def import_donnees_get_file_sample(): def import_donnees_get_file_sample():
""" """
Permet de récupérer un fichier exemple vide pour pouvoir importer des entreprises Permet de récupérer un fichier exemple vide pour pouvoir importer des entreprises
@ -1771,7 +1771,7 @@ def import_donnees_get_file_sample():
@bp.route("/import_donnees", methods=["GET", "POST"]) @bp.route("/import_donnees", methods=["GET", "POST"])
@permission_required(Permission.RelationsEntreprisesExport) @permission_required(Permission.RelationsEntrepExport)
def import_donnees(): def import_donnees():
""" """
Permet d'importer des entreprises à partir d'un fichier excel (.xlsx) Permet d'importer des entreprises à partir d'un fichier excel (.xlsx)
@ -1850,7 +1850,7 @@ def import_donnees():
@bp.route( @bp.route(
"/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/get_offre_file/<string:filedir>/<string:filename>" "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/get_offre_file/<string:filedir>/<string:filename>"
) )
@permission_required(Permission.RelationsEntreprisesView) @permission_required(Permission.RelationsEntrepView)
def get_offre_file(entreprise_id, offre_id, filedir, filename): def get_offre_file(entreprise_id, offre_id, filedir, filename):
""" """
Permet de télécharger un fichier d'une offre Permet de télécharger un fichier d'une offre
@ -1884,7 +1884,7 @@ def get_offre_file(entreprise_id, offre_id, filedir, filename):
"/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/add_offre_file", "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/add_offre_file",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def add_offre_file(entreprise_id, offre_id): def add_offre_file(entreprise_id, offre_id):
""" """
Permet d'ajouter un fichier à une offre Permet d'ajouter un fichier à une offre
@ -1927,7 +1927,7 @@ def add_offre_file(entreprise_id, offre_id):
"/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/delete_offre_file/<string:filedir>", "/fiche_entreprise/<int:entreprise_id>/offre/<int:offre_id>/delete_offre_file/<string:filedir>",
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@permission_required(Permission.RelationsEntreprisesChange) @permission_required(Permission.RelationsEntrepEdit)
def delete_offre_file(entreprise_id, offre_id, filedir): def delete_offre_file(entreprise_id, offre_id, filedir):
""" """
Permet de supprimer un fichier d'une offre Permet de supprimer un fichier d'une offre
@ -1959,7 +1959,7 @@ def delete_offre_file(entreprise_id, offre_id, filedir):
) )
) )
return render_template( return render_template(
"entreprises/form_confirmation.j2", "form_confirmation.j2",
title="Suppression fichier d'une offre", title="Suppression fichier d'une offre",
form=form, form=form,
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",

17
app/forms/generic.py Normal file
View File

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
"""Formulaires génériques
"""
from flask_wtf import FlaskForm
from wtforms import (
SubmitField,
)
SUBMIT_MARGE = {"style": "margin-bottom: 10px;"}
class SimpleConfirmationForm(FlaskForm):
"bête dialogue de confirmation"
submit = SubmitField("OK", render_kw=SUBMIT_MARGE)
cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

View File

@ -0,0 +1,58 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# ScoDoc
#
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""
Formulaires création département
"""
from flask_wtf import FlaskForm
from wtforms import SubmitField, validators
from wtforms.fields.simple import StringField, BooleanField
from app.models import SHORT_STR_LEN
class CreateRoleForm(FlaskForm):
"""Formulaire création rôle"""
name = StringField(
label="Nom du rôle",
validators=[
validators.regexp(
r"^[a-zA-Z0-9]*$",
message="Ne doit comporter que lettres et des chiffres",
),
validators.Length(
max=SHORT_STR_LEN,
message=f"Le nom ne doit pas dépasser {SHORT_STR_LEN} caractères",
),
validators.DataRequired("vous devez spécifier le nom du rôle"),
],
)
submit = SubmitField("Créer ce rôle")
cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})

View File

@ -424,7 +424,7 @@ class FormSemestre(db.Model):
def can_be_edited_by(self, user): def can_be_edited_by(self, user):
"""Vrai si user peut modifier ce semestre (est chef ou l'un des responsables)""" """Vrai si user peut modifier ce semestre (est chef ou l'un des responsables)"""
if not user.has_permission(Permission.ScoImplement): # pas chef if not user.has_permission(Permission.EditFormSemestre): # pas chef
if not self.resp_can_edit or user.id not in [ if not self.resp_can_edit or user.id not in [
resp.id for resp in self.responsables resp.id for resp in self.responsables
]: ]:
@ -607,7 +607,7 @@ class FormSemestre(db.Model):
def est_chef_or_diretud(self, user: User = None): def est_chef_or_diretud(self, user: User = None):
"Vrai si utilisateur (par def. current) est admin, chef dept ou responsable du semestre" "Vrai si utilisateur (par def. current) est admin, chef dept ou responsable du semestre"
user = user or current_user user = user or current_user
return user.has_permission(Permission.ScoImplement) or self.est_responsable( return user.has_permission(Permission.EditFormSemestre) or self.est_responsable(
user user
) )
@ -618,7 +618,7 @@ class FormSemestre(db.Model):
if not self.etat: if not self.etat:
return False # semestre verrouillé return False # semestre verrouillé
user = user or current_user user = user or current_user
if user.has_permission(Permission.ScoEtudChangeGroups): if user.has_permission(Permission.EtudChangeGroups):
return True # typiquement admin, chef dept return True # typiquement admin, chef dept
return self.est_responsable(user) return self.est_responsable(user)
@ -632,9 +632,9 @@ class FormSemestre(db.Model):
def can_edit_pv(self, user: User = None): def can_edit_pv(self, user: User = None):
"Vrai si utilisateur (par def. current) peut editer un PV de jury de ce semestre" "Vrai si utilisateur (par def. current) peut editer un PV de jury de ce semestre"
user = user or current_user user = user or current_user
# Autorise les secrétariats, repérés via la permission ScoEtudChangeAdr # Autorise les secrétariats, repérés via la permission EtudChangeAdr
return self.est_chef_or_diretud(user) or user.has_permission( return self.est_chef_or_diretud(user) or user.has_permission(
Permission.ScoEtudChangeAdr Permission.EtudChangeAdr
) )
def annee_scolaire(self) -> int: def annee_scolaire(self) -> int:

View File

@ -107,7 +107,7 @@ class ModuleImpl(db.Model):
""" """
# acces pour resp. moduleimpl et resp. form semestre (dir etud) # acces pour resp. moduleimpl et resp. form semestre (dir etud)
if ( if (
user.has_permission(Permission.ScoEditAllEvals) user.has_permission(Permission.EditAllEvals)
or user.id == self.responsable_id or user.id == self.responsable_id
or user.id in (r.id for r in self.formsemestre.responsables) or user.id in (r.id for r in self.formsemestre.responsables)
): ):
@ -131,7 +131,7 @@ class ModuleImpl(db.Model):
if not self.formsemestre.etat: if not self.formsemestre.etat:
return False # semestre verrouillé return False # semestre verrouillé
is_dir_etud = user.id in (u.id for u in self.formsemestre.responsables) is_dir_etud = user.id in (u.id for u in self.formsemestre.responsables)
can_edit_all_notes = user.has_permission(Permission.ScoEditAllNotes) can_edit_all_notes = user.has_permission(Permission.EditAllNotes)
if sco_cursus_dut.formsemestre_has_decisions(self.formsemestre_id): if sco_cursus_dut.formsemestre_has_decisions(self.formsemestre_id):
# il y a des décisions de jury dans ce semestre ! # il y a des décisions de jury dans ce semestre !
return can_edit_all_notes or is_dir_etud return can_edit_all_notes or is_dir_etud
@ -155,7 +155,7 @@ class ModuleImpl(db.Model):
return False return False
# -- check access # -- check access
# admin ou resp. semestre avec flag resp_can_change_resp # admin ou resp. semestre avec flag resp_can_change_resp
if user.has_permission(Permission.ScoImplement): if user.has_permission(Permission.EditFormSemestre):
return True return True
if ( if (
user.id in [resp.id for resp in self.formsemestre.responsables] user.id in [resp.id for resp in self.formsemestre.responsables]

View File

@ -56,18 +56,18 @@ def sidebar_common():
<a href="{scu.NotesURL()}" class="sidebar">Programmes</a> <br> <a href="{scu.NotesURL()}" class="sidebar">Programmes</a> <br>
""" """
] ]
if current_user.has_permission(Permission.ScoAbsChange): if current_user.has_permission(Permission.AbsChange):
H.append( H.append(
f""" <a href="{scu.AssiduitesURL()}" class="sidebar">Assiduité</a> <br> """ f""" <a href="{scu.AssiduitesURL()}" class="sidebar">Assiduité</a> <br> """
) )
if current_user.has_permission( if current_user.has_permission(
Permission.ScoUsersAdmin Permission.UsersAdmin
) or current_user.has_permission(Permission.ScoUsersView): ) or current_user.has_permission(Permission.UsersView):
H.append( H.append(
f"""<a href="{scu.UsersURL()}" class="sidebar">Utilisateurs</a> <br>""" f"""<a href="{scu.UsersURL()}" class="sidebar">Utilisateurs</a> <br>"""
) )
if current_user.has_permission(Permission.ScoChangePreferences): if current_user.has_permission(Permission.EditPreferences):
H.append( H.append(
f"""<a href="{url_for("scolar.edit_preferences", scodoc_dept=g.scodoc_dept)}" f"""<a href="{url_for("scolar.edit_preferences", scodoc_dept=g.scodoc_dept)}"
class="sidebar">Paramétrage</a> <br>""" class="sidebar">Paramétrage</a> <br>"""
@ -126,7 +126,7 @@ def sidebar(etudid: int = None):
<br>{ nbabsjust } J., { nbabsnj } N.J.</span>""" <br>{ nbabsjust } J., { nbabsnj } N.J.</span>"""
) )
H.append("<ul>") H.append("<ul>")
if current_user.has_permission(Permission.ScoAbsChange): if current_user.has_permission(Permission.AbsChange):
H.append( H.append(
f""" f"""
<li><a href="{ url_for('assiduites.signal_assiduites_etud', scodoc_dept=g.scodoc_dept, etudid=etudid) }">Ajouter</a></li> <li><a href="{ url_for('assiduites.signal_assiduites_etud', scodoc_dept=g.scodoc_dept, etudid=etudid) }">Ajouter</a></li>

View File

@ -58,7 +58,7 @@ ETUDS_ARCHIVER = EtudsArchiver()
def can_edit_etud_archive(authuser): def can_edit_etud_archive(authuser):
"""True si l'utilisateur peut modifier les archives etudiantes""" """True si l'utilisateur peut modifier les archives etudiantes"""
return authuser.has_permission(Permission.ScoEtudAddAnnotations) return authuser.has_permission(Permission.EtudAddAnnotations)
def etud_list_archives_html(etud: Identite): def etud_list_archives_html(etud: Identite):

View File

@ -954,7 +954,7 @@ def can_send_bulletin_by_mail(formsemestre_id):
sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem = sco_formsemestre.get_formsemestre(formsemestre_id)
return ( return (
sco_preferences.get_preference("bul_mail_allowed_for_all", formsemestre_id) sco_preferences.get_preference("bul_mail_allowed_for_all", formsemestre_id)
or current_user.has_permission(Permission.ScoImplement) or current_user.has_permission(Permission.EditFormSemestre)
or current_user.id in sem["responsables"] or current_user.id in sem["responsables"]
) )
@ -1213,7 +1213,7 @@ def make_menu_autres_operations(
}, },
"enabled": ( "enabled": (
formsemestre.can_be_edited_by(current_user) formsemestre.can_be_edited_by(current_user)
or current_user.has_permission(Permission.ScoEtudInscrit) or current_user.has_permission(Permission.EtudInscrit)
), ),
}, },
{ {
@ -1223,7 +1223,7 @@ def make_menu_autres_operations(
"formsemestre_id": formsemestre.id, "formsemestre_id": formsemestre.id,
"etudid": etud.id, "etudid": etud.id,
}, },
"enabled": current_user.has_permission(Permission.ScoImplement), "enabled": current_user.has_permission(Permission.EditFormSemestre),
}, },
{ {
"title": "Gérer les validations d'UEs antérieures", "title": "Gérer les validations d'UEs antérieures",

View File

@ -327,9 +327,9 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
H.append("""<p class="bull_situation">%(situation)s</p>""" % I) H.append("""<p class="bull_situation">%(situation)s</p>""" % I)
# --- Appreciations # --- Appreciations
# le dir. des etud peut ajouter des appreciations, # le dir. des etud peut ajouter des appreciations,
# mais aussi le chef (perm. ScoEtudInscrit) # mais aussi le chef (perm. EtudInscrit)
can_edit_app = (authuser.id in self.infos["responsables"]) or ( can_edit_app = (authuser.id in self.infos["responsables"]) or (
authuser.has_permission(Permission.ScoEtudInscrit) authuser.has_permission(Permission.EtudInscrit)
) )
H.append('<div class="bull_appreciations">') H.append('<div class="bull_appreciations">')
appreciations = BulAppreciations.get_appreciations_list( appreciations = BulAppreciations.get_appreciations_list(

View File

@ -155,9 +155,9 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
# ---- APPRECIATIONS # ---- APPRECIATIONS
# le dir. des etud peut ajouter des appreciations, # le dir. des etud peut ajouter des appreciations,
# mais aussi le chef (perm. ScoEtudInscrit) # mais aussi le chef (perm. EtudInscrit)
can_edit_app = (self.formsemestre.est_responsable(self.authuser)) or ( can_edit_app = (self.formsemestre.est_responsable(self.authuser)) or (
self.authuser.has_permission(Permission.ScoEtudInscrit) self.authuser.has_permission(Permission.EtudInscrit)
) )
H.append('<div class="bull_appreciations">') H.append('<div class="bull_appreciations">')
appreciations = BulAppreciations.get_appreciations_list( appreciations = BulAppreciations.get_appreciations_list(

View File

@ -148,7 +148,7 @@ def index_html(showcodes=0, showsemtable=0):
</p>""" </p>"""
) )
# #
if current_user.has_permission(Permission.ScoEtudInscrit): if current_user.has_permission(Permission.EtudInscrit):
H.append( H.append(
"""<hr> """<hr>
<h3>Gestion des étudiants</h3> <h3>Gestion des étudiants</h3>
@ -164,7 +164,7 @@ def index_html(showcodes=0, showsemtable=0):
""" """
) )
# #
if current_user.has_permission(Permission.ScoEditApo): if current_user.has_permission(Permission.EditApogee):
H.append( H.append(
f"""<hr> f"""<hr>
<h3>Exports Apogée</h3> <h3>Exports Apogée</h3>
@ -247,7 +247,7 @@ def _sem_table_gt(sems, showcodes=False):
columns_ids = ("formsemestre_id",) + columns_ids columns_ids = ("formsemestre_id",) + columns_ids
html_class = "stripe cell-border compact hover order-column table_leftalign semlist" html_class = "stripe cell-border compact hover order-column table_leftalign semlist"
if current_user.has_permission(Permission.ScoEditApo): if current_user.has_permission(Permission.EditApogee):
html_class += " apo_editable" html_class += " apo_editable"
tab = GenTable( tab = GenTable(
titles={ titles={

View File

@ -908,7 +908,7 @@ def module_table(formation_id):
<ul class="notes_module_list"> <ul class="notes_module_list">
""", """,
] ]
editable = current_user.has_permission(Permission.ScoChangeFormation) editable = current_user.has_permission(Permission.EditFormation)
for module_dict in module_list(args={"formation_id": formation_id}): for module_dict in module_list(args={"formation_id": formation_id}):
H.append('<li class="notes_module_list">%s' % module_dict) H.append('<li class="notes_module_list">%s' % module_dict)

View File

@ -718,7 +718,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
} }
ues_with_duplicated_code = [ue for ue in ues if ue["ue_code"] in duplicated_codes] ues_with_duplicated_code = [ue for ue in ues if ue["ue_code"] in duplicated_codes]
has_perm_change = current_user.has_permission(Permission.ScoChangeFormation) has_perm_change = current_user.has_permission(Permission.EditFormation)
# editable = (not locked) and has_perm_change # editable = (not locked) and has_perm_change
# On autorise maintenant la modification des formations qui ont # On autorise maintenant la modification des formations qui ont
# des semestres verrouillés, sauf si cela affect les notes passées # des semestres verrouillés, sauf si cela affect les notes passées
@ -727,7 +727,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
# - pas de changement des codes d'UE utilisés dans des semestres verrouillés # - pas de changement des codes d'UE utilisés dans des semestres verrouillés
editable = has_perm_change editable = has_perm_change
tag_editable = ( tag_editable = (
current_user.has_permission(Permission.ScoEditFormationTags) or has_perm_change current_user.has_permission(Permission.EditFormationTags) or has_perm_change
) )
if locked: if locked:
lockicon = scu.icontag("lock32_img", title="verrouillé") lockicon = scu.icontag("lock32_img", title="verrouillé")
@ -835,7 +835,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
</a>&nbsp;""" </a>&nbsp;"""
msg_refcomp = "changer" msg_refcomp = "changer"
H.append(f"""<ul><li>{descr_refcomp}""") H.append(f"""<ul><li>{descr_refcomp}""")
if current_user.has_permission(Permission.ScoChangeFormation): if current_user.has_permission(Permission.EditFormation):
if ( if (
formation.referentiel_competence is None formation.referentiel_competence is None
or formation.formsemestres.count() == 0 or formation.formsemestres.count() == 0
@ -1021,7 +1021,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
H.append("</li>") H.append("</li>")
H.append("</ul>") H.append("</ul>")
if current_user.has_permission(Permission.ScoImplement): if current_user.has_permission(Permission.EditFormSemestre):
H.append( H.append(
f"""<ul> f"""<ul>
<li><a class="stdlink" href="{ <li><a class="stdlink" href="{

View File

@ -50,7 +50,7 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
T = [] T = []
formation = Formation.query.get_or_404(formation_id) formation = Formation.query.get_or_404(formation_id)
ues = formation.ues.order_by(UniteEns.semestre_idx, UniteEns.numero) ues = formation.ues.order_by(UniteEns.semestre_idx, UniteEns.numero)
can_edit = current_user.has_permission(Permission.ScoChangeFormation) can_edit = current_user.has_permission(Permission.EditFormation)
li = 0 li = 0
for ue in ues: for ue in ues:
# L'UE # L'UE
@ -138,7 +138,7 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
title = f"""Formation {formation.titre} ({formation.acronyme}) title = f"""Formation {formation.titre} ({formation.acronyme})
[version {formation.version}] code {formation.formation_code}""" [version {formation.version}] code {formation.formation_code}"""
html_class = "stripe cell-border compact hover order-column formation_table_recap" html_class = "stripe cell-border compact hover order-column formation_table_recap"
if current_user.has_permission(Permission.ScoEditApo): if current_user.has_permission(Permission.EditApogee):
html_class += " apo_editable" html_class += " apo_editable"
tab = GenTable( tab = GenTable(

View File

@ -498,7 +498,7 @@ def formation_list_table() -> GenTable:
"edit_img", border="0", alt="modifier", title="Modifier titres et code" "edit_img", border="0", alt="modifier", title="Modifier titres et code"
) )
editable = current_user.has_permission(Permission.ScoChangeFormation) editable = current_user.has_permission(Permission.EditFormation)
# Traduit/ajoute des champs à afficher: # Traduit/ajoute des champs à afficher:
rows = [] rows = []

View File

@ -144,7 +144,7 @@ def formsemestre_editwithmodules(formsemestre_id):
def can_edit_sem(formsemestre_id: int = None, sem=None): def can_edit_sem(formsemestre_id: int = None, sem=None):
"""Return sem if user can edit it, False otherwise""" """Return sem if user can edit it, False otherwise"""
sem = sem or sco_formsemestre.get_formsemestre(formsemestre_id) sem = sem or sco_formsemestre.get_formsemestre(formsemestre_id)
if not current_user.has_permission(Permission.ScoImplement): # pas chef if not current_user.has_permission(Permission.EditFormSemestre): # pas chef
if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]: if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]:
return False return False
return sem return sem
@ -162,9 +162,9 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N
"Form choix modules / responsables et création formsemestre" "Form choix modules / responsables et création formsemestre"
vals = scu.get_request_args() vals = scu.get_request_args()
# Fonction accessible à tous, contrôle d'acces à la main: # Fonction accessible à tous, contrôle d'acces à la main:
if not current_user.has_permission(Permission.ScoImplement): if not current_user.has_permission(Permission.EditFormSemestre):
if not edit: if not edit:
# il faut ScoImplement pour créer un semestre # il faut EditFormSemestre pour créer un semestre
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
else: else:
if not formsemestre.resp_can_edit or current_user.id not in ( if not formsemestre.resp_can_edit or current_user.id not in (
@ -485,7 +485,7 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N
}, },
), ),
] ]
if current_user.has_permission(Permission.ScoImplement): if current_user.has_permission(Permission.EditFormSemestre):
modform += [ modform += [
( (
"resp_can_edit", "resp_can_edit",
@ -1539,7 +1539,7 @@ def do_formsemestre_delete(formsemestre_id):
# --------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------
def formsemestre_edit_options(formsemestre_id): def formsemestre_edit_options(formsemestre_id):
"""dialog to change formsemestre options """dialog to change formsemestre options
(accessible par ScoImplement ou dir. etudes) (accessible par EditFormSemestre ou dir. etudes)
""" """
log("formsemestre_edit_options") log("formsemestre_edit_options")
ok, err = sco_permissions_check.check_access_diretud(formsemestre_id) ok, err = sco_permissions_check.check_access_diretud(formsemestre_id)

View File

@ -157,7 +157,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
# L'utilisateur est-il resp. du semestre ? # L'utilisateur est-il resp. du semestre ?
is_responsable = current_user.id in (u.id for u in formsemestre.responsables) is_responsable = current_user.id in (u.id for u in formsemestre.responsables)
# A le droit de changer le semestre (déverrouiller, préférences bul., ...): # A le droit de changer le semestre (déverrouiller, préférences bul., ...):
has_perm_change_sem = current_user.has_permission(Permission.ScoImplement) or ( has_perm_change_sem = current_user.has_permission(Permission.EditFormSemestre) or (
formsemestre.resp_can_edit and is_responsable formsemestre.resp_can_edit and is_responsable
) )
# Peut modifier le semestre (si n'est pas verrouillé): # Peut modifier le semestre (si n'est pas verrouillé):
@ -236,7 +236,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"title": "Cloner ce semestre", "title": "Cloner ce semestre",
"endpoint": "notes.formsemestre_clone", "endpoint": "notes.formsemestre_clone",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoImplement), "enabled": current_user.has_permission(Permission.EditFormSemestre),
"helpmsg": "", "helpmsg": "",
}, },
{ {
@ -246,7 +246,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"formation_id": formsemestre.formation_id, "formation_id": formsemestre.formation_id,
}, },
"enabled": current_user.has_permission(Permission.ScoChangeFormation) "enabled": current_user.has_permission(Permission.EditFormation)
and formsemestre.etat, and formsemestre.etat,
"helpmsg": "", "helpmsg": "",
}, },
@ -254,7 +254,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"title": "Supprimer ce semestre", "title": "Supprimer ce semestre",
"endpoint": "notes.formsemestre_delete", "endpoint": "notes.formsemestre_delete",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoImplement), "enabled": current_user.has_permission(Permission.EditFormSemestre),
"helpmsg": "", "helpmsg": "",
}, },
] ]
@ -283,7 +283,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"title": "Passage des étudiants depuis d'autres semestres", "title": "Passage des étudiants depuis d'autres semestres",
"endpoint": "notes.formsemestre_inscr_passage", "endpoint": "notes.formsemestre_inscr_passage",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.EtudInscrit)
and formsemestre.etat, and formsemestre.etat,
}, },
{ {
@ -298,14 +298,14 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"title": "Inscrire un étudiant", "title": "Inscrire un étudiant",
"endpoint": "notes.formsemestre_inscription_with_modules_etud", "endpoint": "notes.formsemestre_inscription_with_modules_etud",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.EtudInscrit)
and formsemestre.etat, and formsemestre.etat,
}, },
{ {
"title": "Importer des étudiants dans ce semestre (table Excel)", "title": "Importer des étudiants dans ce semestre (table Excel)",
"endpoint": "scolar.form_students_import_excel", "endpoint": "scolar.form_students_import_excel",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.EtudInscrit)
and formsemestre.etat, and formsemestre.etat,
}, },
{ {
@ -318,7 +318,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"title": "Resynchroniser données identité", "title": "Resynchroniser données identité",
"endpoint": "scolar.formsemestre_import_etud_admission", "endpoint": "scolar.formsemestre_import_etud_admission",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudChangeAdr) "enabled": current_user.has_permission(Permission.EtudChangeAdr)
and sco_preferences.get_preference("portal_url"), and sco_preferences.get_preference("portal_url"),
}, },
{ {
@ -812,7 +812,7 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str:
"""La section avec les groupes et l'assiduité""" """La section avec les groupes et l'assiduité"""
H = [] H = []
# pas de menu absences si pas autorise: # pas de menu absences si pas autorise:
can_edit_abs = current_user.has_permission(Permission.ScoAbsChange) can_edit_abs = current_user.has_permission(Permission.AbsChange)
# #
H.append( H.append(
f"""<h3>Groupes et absences de {formsemestre.titre} f"""<h3>Groupes et absences de {formsemestre.titre}
@ -1080,7 +1080,7 @@ def formsemestre_status(formsemestre_id=None, check_parcours=True):
) )
can_edit = formsemestre.can_be_edited_by(current_user) can_edit = formsemestre.can_be_edited_by(current_user)
can_change_all_notes = current_user.has_permission(Permission.ScoEditAllNotes) or ( can_change_all_notes = current_user.has_permission(Permission.EditAllNotes) or (
current_user.id in [resp.id for resp in formsemestre.responsables] current_user.id in [resp.id for resp in formsemestre.responsables]
) )
use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id) use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id)

View File

@ -1291,7 +1291,7 @@ def _get_etud_ue_cap_html(etud: Identite, formsemestre: FormSemestre) -> str:
origine += f" (<b>S{validation.semestre_id}</b>)" origine += f" (<b>S{validation.semestre_id}</b>)"
H.append(f"""<li>{validation.html()}""") H.append(f"""<li>{validation.html()}""")
if (validation.formsemestre and validation.formsemestre.can_edit_jury()) or ( if (validation.formsemestre and validation.formsemestre.can_edit_jury()) or (
current_user and current_user.has_permission(Permission.ScoEtudInscrit) current_user and current_user.has_permission(Permission.EtudInscrit)
): ):
H.append( H.append(
f""" f"""

View File

@ -865,13 +865,13 @@ def tab_absences_html(groups_infos, etat=None):
# Lien pour verif codes INE/NIP # Lien pour verif codes INE/NIP
# (pour tous les etudiants du semestre) # (pour tous les etudiants du semestre)
group_id = sco_groups.get_default_group(groups_infos.formsemestre_id) group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
if authuser.has_permission(Permission.ScoEtudInscrit): if authuser.has_permission(Permission.EtudInscrit):
H.append( H.append(
'<li><a class="stdlink" href="check_group_apogee?group_id=%s&etat=%s">Vérifier codes Apogée</a> (de tous les groupes)</li>' '<li><a class="stdlink" href="check_group_apogee?group_id=%s&etat=%s">Vérifier codes Apogée</a> (de tous les groupes)</li>'
% (group_id, etat or "") % (group_id, etat or "")
) )
# Lien pour ajout fichiers étudiants # Lien pour ajout fichiers étudiants
if authuser.has_permission(Permission.ScoEtudAddAnnotations): if authuser.has_permission(Permission.EtudAddAnnotations):
H.append( H.append(
"""<li><a class="stdlink" href="etudarchive_import_files_form?group_id=%s">Télécharger des fichiers associés aux étudiants (e.g. dossiers d'admission)</a></li>""" """<li><a class="stdlink" href="etudarchive_import_files_form?group_id=%s">Télécharger des fichiers associés aux étudiants (e.g. dossiers d'admission)</a></li>"""
% (group_id) % (group_id)
@ -894,7 +894,7 @@ def tab_photos_html(groups_infos, etat=None):
def form_choix_jour_saisie_hebdo(groups_infos, moduleimpl_id=None): def form_choix_jour_saisie_hebdo(groups_infos, moduleimpl_id=None):
"""Formulaire choix jour semaine pour saisie.""" """Formulaire choix jour semaine pour saisie."""
authuser = current_user authuser = current_user
if not authuser.has_permission(Permission.ScoAbsChange): if not authuser.has_permission(Permission.AbsChange):
return "" return ""
return f""" return f"""
<button onclick="window.location='{ <button onclick="window.location='{
@ -913,7 +913,7 @@ def form_choix_jour_saisie_hebdo(groups_infos, moduleimpl_id=None):
# Saisie de l'assiduité par semaine # Saisie de l'assiduité par semaine
def form_choix_saisie_semaine(groups_infos): def form_choix_saisie_semaine(groups_infos):
authuser = current_user authuser = current_user
if not authuser.has_permission(Permission.ScoAbsChange): if not authuser.has_permission(Permission.AbsChange):
return "" return ""
query_args = parse_qs(request.query_string) query_args = parse_qs(request.query_string)
moduleimpl_id = query_args.get("moduleimpl_id", [None])[0] moduleimpl_id = query_args.get("moduleimpl_id", [None])[0]

View File

@ -375,7 +375,7 @@ def can_change_module_resp(moduleimpl_id):
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
# -- check access # -- check access
# admin ou resp. semestre avec flag resp_can_change_resp # admin ou resp. semestre avec flag resp_can_change_resp
if not current_user.has_permission(Permission.ScoImplement) and ( if not current_user.has_permission(Permission.EditFormSemestre) and (
(current_user.id not in sem["responsables"]) or (not sem["resp_can_change_ens"]) (current_user.id not in sem["responsables"]) or (not sem["resp_can_change_ens"])
): ):
raise AccessDenied(f"Modification impossible pour {current_user}") raise AccessDenied(f"Modification impossible pour {current_user}")
@ -396,7 +396,7 @@ def can_change_ens(moduleimpl_id, raise_exc=True):
# admin, resp. module ou resp. semestre # admin, resp. module ou resp. semestre
if ( if (
current_user.id != M["responsable_id"] current_user.id != M["responsable_id"]
and not current_user.has_permission(Permission.ScoImplement) and not current_user.has_permission(Permission.EditFormSemestre)
and (current_user.id not in sem["responsables"]) and (current_user.id not in sem["responsables"])
): ):
if raise_exc: if raise_exc:

View File

@ -278,9 +278,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
set_all = set([x["etudid"] for x in inscrits]) set_all = set([x["etudid"] for x in inscrits])
partitions, _ = sco_groups.get_formsemestre_groups(formsemestre_id) partitions, _ = sco_groups.get_formsemestre_groups(formsemestre_id)
can_change = ( can_change = authuser.has_permission(Permission.EtudInscrit) and formsemestre.etat
authuser.has_permission(Permission.ScoEtudInscrit) and formsemestre.etat
)
# Décrit les inscriptions aux modules: # Décrit les inscriptions aux modules:
commons = [] # modules communs a tous les etuds du semestre commons = [] # modules communs a tous les etuds du semestre

View File

@ -290,7 +290,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
H.append( H.append(
f"""<tr><td class="fichetitre2">Inscrits: </td><td> {len(mod_inscrits)} étudiants""" f"""<tr><td class="fichetitre2">Inscrits: </td><td> {len(mod_inscrits)} étudiants"""
) )
if current_user.has_permission(Permission.ScoEtudInscrit): if current_user.has_permission(Permission.EtudInscrit):
H.append( H.append(
f"""<a class="stdlink" style="margin-left:2em;" href="moduleimpl_inscriptions_edit?moduleimpl_id={modimpl.id}">modifier</a>""" f"""<a class="stdlink" style="margin-left:2em;" href="moduleimpl_inscriptions_edit?moduleimpl_id={modimpl.id}">modifier</a>"""
) )
@ -317,10 +317,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
) )
# Adapté à partir d'une suggestion de DS (Le Havre) # Adapté à partir d'une suggestion de DS (Le Havre)
# Liens saisies absences seulement si permission et date courante dans le semestre # Liens saisies absences seulement si permission et date courante dans le semestre
if ( if current_user.has_permission(Permission.AbsChange) and formsemestre.est_courant():
current_user.has_permission(Permission.ScoAbsChange)
and formsemestre.est_courant()
):
group_id = sco_groups.get_default_group(formsemestre_id) group_id = sco_groups.get_default_group(formsemestre_id)
H.append( H.append(
f""" f"""

View File

@ -70,8 +70,8 @@ def _menu_scolarite(
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
return lockicon # no menu return lockicon # no menu
if not authuser.has_permission( if not authuser.has_permission(
Permission.ScoEtudInscrit Permission.EtudInscrit
) and not authuser.has_permission(Permission.ScoEtudChangeGroups): ) and not authuser.has_permission(Permission.EtudChangeGroups):
return "" # no menu return "" # no menu
args = {"etudid": etudid, "formsemestre_id": formsemestre.id} args = {"etudid": etudid, "formsemestre_id": formsemestre.id}
@ -92,7 +92,7 @@ def _menu_scolarite(
def_url = "scolar.do_cancel_def" def_url = "scolar.do_cancel_def"
def_enabled = ( def_enabled = (
(etat_inscription != scu.DEMISSION) (etat_inscription != scu.DEMISSION)
and authuser.has_permission(Permission.ScoEtudInscrit) and authuser.has_permission(Permission.EtudInscrit)
and not locked and not locked
) )
items = [ items = [
@ -100,15 +100,13 @@ def _menu_scolarite(
"title": dem_title, "title": dem_title,
"endpoint": dem_url, "endpoint": dem_url,
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoEtudInscrit) "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
and not locked,
}, },
{ {
"title": "Validation du semestre (jury)", "title": "Validation du semestre (jury)",
"endpoint": "notes.formsemestre_validation_etud_form", "endpoint": "notes.formsemestre_validation_etud_form",
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoEtudInscrit) "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
and not locked,
}, },
{ {
"title": def_title, "title": def_title,
@ -120,15 +118,13 @@ def _menu_scolarite(
"title": "Inscrire à un module optionnel (ou au sport)", "title": "Inscrire à un module optionnel (ou au sport)",
"endpoint": "notes.formsemestre_inscription_option", "endpoint": "notes.formsemestre_inscription_option",
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoEtudInscrit) "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
and not locked,
}, },
{ {
"title": "Désinscrire (en cas d'erreur)", "title": "Désinscrire (en cas d'erreur)",
"endpoint": "notes.formsemestre_desinscription", "endpoint": "notes.formsemestre_desinscription",
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoEtudInscrit) "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
and not locked,
}, },
{ {
"title": "Gérer les validations d'UEs antérieures", "title": "Gérer les validations d'UEs antérieures",
@ -140,19 +136,19 @@ def _menu_scolarite(
"title": "Inscrire à un autre semestre", "title": "Inscrire à un autre semestre",
"endpoint": "notes.formsemestre_inscription_with_modules_form", "endpoint": "notes.formsemestre_inscription_with_modules_form",
"args": {"etudid": etudid}, "args": {"etudid": etudid},
"enabled": authuser.has_permission(Permission.ScoEtudInscrit), "enabled": authuser.has_permission(Permission.EtudInscrit),
}, },
{ {
"title": "Enregistrer un semestre effectué ailleurs", "title": "Enregistrer un semestre effectué ailleurs",
"endpoint": "notes.formsemestre_ext_create_form", "endpoint": "notes.formsemestre_ext_create_form",
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoImplement), "enabled": authuser.has_permission(Permission.EditFormSemestre),
}, },
{ {
"title": "Affecter les notes manquantes", "title": "Affecter les notes manquantes",
"endpoint": "notes.formsemestre_note_etuds_sans_notes", "endpoint": "notes.formsemestre_note_etuds_sans_notes",
"args": args, "args": args,
"enabled": authuser.has_permission(Permission.ScoEditAllNotes), "enabled": authuser.has_permission(Permission.EditAllNotes),
}, },
] ]
@ -235,7 +231,7 @@ def ficheEtud(etudid=None):
else: else:
info["emaillink"] = "<em>(pas d'adresse e-mail)</em>" info["emaillink"] = "<em>(pas d'adresse e-mail)</em>"
# Champ dépendant des permissions: # Champ dépendant des permissions:
if authuser.has_permission(Permission.ScoEtudChangeAdr): if authuser.has_permission(Permission.EtudChangeAdr):
info[ info[
"modifadresse" "modifadresse"
] = f"""<a class="stdlink" href="{ ] = f"""<a class="stdlink" href="{
@ -333,7 +329,7 @@ def ficheEtud(etudid=None):
}">Visualiser les compétences BUT</a> }">Visualiser les compétences BUT</a>
</span> </span>
""" """
if authuser.has_permission(Permission.ScoEtudInscrit): if authuser.has_permission(Permission.EtudInscrit):
info[ info[
"link_inscrire_ailleurs" "link_inscrire_ailleurs"
] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{ ] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
@ -351,7 +347,7 @@ def ficheEtud(etudid=None):
else: else:
# non inscrit # non inscrit
l = [f"""<p><b>Étudiant{info["ne"]} non inscrit{info["ne"]}"""] l = [f"""<p><b>Étudiant{info["ne"]} non inscrit{info["ne"]}"""]
if authuser.has_permission(Permission.ScoEtudInscrit): if authuser.has_permission(Permission.EtudInscrit):
l.append( l.append(
f"""<a href="{ f"""<a href="{
url_for("notes.formsemestre_inscription_with_modules_form", url_for("notes.formsemestre_inscription_with_modules_form",
@ -634,25 +630,25 @@ def menus_etud(etudid):
"title": "Changer la photo", "title": "Changer la photo",
"endpoint": "scolar.form_change_photo", "endpoint": "scolar.form_change_photo",
"args": {"etudid": etud["etudid"]}, "args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.ScoEtudChangeAdr), "enabled": authuser.has_permission(Permission.EtudChangeAdr),
}, },
{ {
"title": "Changer les données identité/admission", "title": "Changer les données identité/admission",
"endpoint": "scolar.etudident_edit_form", "endpoint": "scolar.etudident_edit_form",
"args": {"etudid": etud["etudid"]}, "args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.ScoEtudInscrit), "enabled": authuser.has_permission(Permission.EtudInscrit),
}, },
{ {
"title": "Copier dans un autre département...", "title": "Copier dans un autre département...",
"endpoint": "scolar.etud_copy_in_other_dept", "endpoint": "scolar.etud_copy_in_other_dept",
"args": {"etudid": etud["etudid"]}, "args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.ScoEtudInscrit), "enabled": authuser.has_permission(Permission.EtudInscrit),
}, },
{ {
"title": "Supprimer cet étudiant...", "title": "Supprimer cet étudiant...",
"endpoint": "scolar.etudident_delete", "endpoint": "scolar.etudident_delete",
"args": {"etudid": etud["etudid"]}, "args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.ScoEtudInscrit), "enabled": authuser.has_permission(Permission.EtudInscrit),
}, },
{ {
"title": "Voir le journal...", "title": "Voir le journal...",

View File

@ -14,51 +14,51 @@ _SCO_PERMISSIONS = (
# - tous rôles lors creation utilisateurs # - tous rôles lors creation utilisateurs
(1 << 1, "ScoSuperAdmin", "Super Administrateur"), (1 << 1, "ScoSuperAdmin", "Super Administrateur"),
(1 << 2, "ScoView", "Voir"), (1 << 2, "ScoView", "Voir"),
(1 << 3, "ScoEnsView", "Voir les parties pour les enseignants"), (1 << 3, "EnsView", "Voir les parties pour les enseignants"),
(1 << 4, "ScoObservateur", "Observer (accès lecture restreint aux bulletins)"), (1 << 4, "Observateur", "Observer (accès lecture restreint aux bulletins)"),
(1 << 5, "ScoUsersAdmin", "Gérer les utilisateurs (de son département)"), (1 << 5, "UsersAdmin", "Gérer les utilisateurs (de son département)"),
(1 << 6, "ScoUsersView", "Voir les utilisateurs (de tous les dépts)"), (1 << 6, "UsersView", "Voir les utilisateurs (de tous les dépts)"),
(1 << 7, "ScoChangePreferences", "Modifier les préférences"), (1 << 7, "EditPreferences", "Modifier les préférences"),
(1 << 8, "ScoChangeFormation", "Changer les formations"), (1 << 8, "EditFormation", "Changer les formations"),
(1 << 9, "ScoEditFormationTags", "Tagguer les formations"), (1 << 9, "EditFormationTags", "Tagguer les formations"),
(1 << 10, "ScoEditAllNotes", "Modifier toutes les notes"), (1 << 10, "EditAllNotes", "Modifier toutes les notes"),
(1 << 11, "ScoEditAllEvals", "Modifier toutes les evaluations"), (1 << 11, "EditAllEvals", "Modifier toutes les evaluations"),
(1 << 12, "ScoImplement", "Mettre en place une formation (créer un semestre)"), (1 << 12, "EditFormSemestre", "Mettre en place une formation (créer un semestre)"),
(1 << 13, "ScoAbsChange", "Saisir des absences"), (1 << 13, "AbsChange", "Saisir des absences"),
(1 << 14, "ScoAbsAddBillet", "Saisir des billets d'absences"), (1 << 14, "AbsAddBillet", "Saisir des billets d'absences"),
# changer adresse/photo ou pour envoyer bulletins par mail ou pour debouche # changer adresse/photo ou pour envoyer bulletins par mail ou pour debouche
(1 << 15, "ScoEtudChangeAdr", "Changer les adresses d'étudiants"), (1 << 15, "EtudChangeAdr", "Changer les adresses d'étudiants"),
( (
1 << 16, 1 << 16,
"APIEditGroups", "APIEditGroups",
"API: Modifier les groupes (obsolete, use ScoEtudChangeGroups)", "API: Modifier les groupes (obsolete, use EtudChangeGroups)",
), ),
(1 << 16, "ScoEtudChangeGroups", "Modifier les groupes"), (1 << 16, "EtudChangeGroups", "Modifier les groupes"),
# aussi pour demissions, diplomes: # aussi pour demissions, diplomes:
(1 << 17, "ScoEtudInscrit", "Inscrire des étudiants"), (1 << 17, "EtudInscrit", "Inscrire des étudiants"),
# aussi pour archives: # aussi pour archives:
(1 << 18, "ScoEtudAddAnnotations", "Éditer les annotations"), (1 << 18, "EtudAddAnnotations", "Éditer les annotations"),
(1 << 19, "ScoEntrepriseView", "Voir la section 'entreprises'"), # inutilisée (1 << 19, "ScoEntrepriseView", "Voir la section 'entreprises'"),
(1 << 20, "ScoEntrepriseChange", "Modifier les entreprises"), # inutilisée (1 << 20, "EntrepriseChange", "Modifier les entreprises"),
(1 << 21, "ScoEditPVJury", "Éditer les PV de jury"), # XXX inutilisée ? (1 << 21, "EditPVJury", "Éditer les PV de jury"),
# ajouter maquettes Apogee (=> chef dept et secr): # ajouter maquettes Apogee (=> chef dept et secr):
(1 << 22, "ScoEditApo", "Ajouter des maquettes Apogées"), (1 << 22, "EditApogee", "Gérer les exports Apogée"),
# Application relations entreprises # Application relations entreprises
(1 << 23, "RelationsEntreprisesView", "Voir l'application relations entreprises"), (1 << 23, "RelationsEntrepView", "Voir l'application relations entreprises"),
(1 << 24, "RelationsEntreprisesChange", "Modifier les entreprises"), (1 << 24, "RelationsEntrepEdit", "Modifier les entreprises"),
(1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"), (1 << 25, "RelationsEntrepSend", "Envoyer des offres"),
(1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"), (1 << 26, "RelationsEntrepValidate", "Valide les entreprises"),
(1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"), (1 << 27, "RelationsEntrepViewCorrs", "Voir les correspondants"),
( (
1 << 28, 1 << 28,
"RelationsEntreprisesExport", "RelationsEntrepExport",
"Exporter les données de l'application relations entreprises", "Exporter les données de l'application relations entreprises",
), ),
(1 << 29, "ScoUsersChangeCASId", "Paramétrer l'id CAS"), (1 << 29, "UsersChangeCASId", "Paramétrer l'id CAS"),
# #
(1 << 40, "ScoEtudChangePhoto", "Modifier la photo d'un étudiant"), # XXX inutilisée ? (1 << 40, "EtudChangePhoto", "Modifier la photo d'un étudiant"),
# Permissions du module Assiduité) # Permissions du module Assiduité)
(1 << 50, "ScoJustifView", "Visualisation des fichiers justificatifs"), (1 << 50, "AbsJustifView", "Visualisation des fichiers justificatifs"),
# Attention: les permissions sont codées sur 64 bits. # Attention: les permissions sont codées sur 64 bits.
) )

View File

@ -35,12 +35,12 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True):
if sco_cursus_dut.formsemestre_has_decisions(sem["formsemestre_id"]): if sco_cursus_dut.formsemestre_has_decisions(sem["formsemestre_id"]):
# il y a des décisions de jury dans ce semestre ! # il y a des décisions de jury dans ce semestre !
return ( return (
authuser.has_permission(Permission.ScoEditAllNotes) authuser.has_permission(Permission.EditAllNotes)
or authuser.id in sem["responsables"] or authuser.id in sem["responsables"]
) )
else: else:
if ( if (
(not authuser.has_permission(Permission.ScoEditAllNotes)) (not authuser.has_permission(Permission.EditAllNotes))
and authuser.id != M["responsable_id"] and authuser.id != M["responsable_id"]
and authuser.id not in sem["responsables"] and authuser.id not in sem["responsables"]
): ):
@ -65,27 +65,29 @@ def can_suppress_annotation(annotation_id):
raise sco_exceptions.ScoValueError("annotation inexistante !") raise sco_exceptions.ScoValueError("annotation inexistante !")
anno = annos[0] anno = annos[0]
return (current_user.user_name == anno["author"]) or current_user.has_permission( return (current_user.user_name == anno["author"]) or current_user.has_permission(
Permission.ScoEtudAddAnnotations Permission.EtudAddAnnotations
) )
def can_edit_suivi(): def can_edit_suivi():
"""Vrai si l'utilisateur peut modifier les informations de suivi sur la page etud" """ """Vrai si l'utilisateur peut modifier les informations de suivi sur la page etud" """
return current_user.has_permission(Permission.ScoEtudChangeAdr) return current_user.has_permission(Permission.EtudChangeAdr)
def is_chef_or_diretud(sem): # remplacé par formsemestre.est_chef_or_diretud def is_chef_or_diretud(sem): # remplacé par formsemestre.est_chef_or_diretud
"Vrai si utilisateur est admin, chef dept ou responsable du semestre" "Vrai si utilisateur est admin, chef dept ou responsable du semestre"
if ( if (
current_user.has_permission(Permission.ScoImplement) current_user.has_permission(Permission.EditFormSemestre)
or current_user.id in sem["responsables"] or current_user.id in sem["responsables"]
): ):
return True return True
return False return False
def check_access_diretud(formsemestre_id, required_permission=Permission.ScoImplement): def check_access_diretud(
"""Check if access granted: responsable or ScoImplement formsemestre_id, required_permission=Permission.EditFormSemestre
):
"""Check if access granted: responsable or EditFormSemestre
Return True|False, HTML_error_page Return True|False, HTML_error_page
""" """
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -131,7 +133,7 @@ def can_handle_passwd(user: User, allow_admindepts=False) -> bool:
if user.user_name == current_user.user_name: if user.user_name == current_user.user_name:
return True return True
# If don't have permission in the current dept, abort # If don't have permission in the current dept, abort
if not current_user.has_permission(Permission.ScoUsersAdmin, g.scodoc_dept): if not current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept):
return False return False
# Now check that current_user can manage users from this departement # Now check that current_user can manage users from this departement
if not current_user.dept: if not current_user.dept:

View File

@ -7,77 +7,72 @@
from app.scodoc.sco_permissions import Permission as p from app.scodoc.sco_permissions import Permission as p
SCO_ROLES_DEFAULTS = { SCO_ROLES_DEFAULTS = {
"Observateur": (p.ScoObservateur,),
"Ens": ( "Ens": (
p.ScoAbsAddBillet, p.AbsAddBillet,
p.ScoAbsChange, p.AbsChange,
p.ScoEnsView, p.EnsView,
p.ScoEntrepriseView, p.EtudAddAnnotations,
p.ScoEtudAddAnnotations, p.Observateur,
p.ScoObservateur, p.UsersView,
p.ScoUsersView,
p.ScoView, p.ScoView,
), ),
"Secr": ( "Secr": (
p.ScoAbsAddBillet, p.AbsAddBillet,
p.ScoAbsChange, p.AbsChange,
p.ScoEditApo, p.EditApogee,
p.ScoEntrepriseChange, p.EtudAddAnnotations,
p.ScoEntrepriseView, p.EtudChangeAdr,
p.ScoEtudAddAnnotations, p.Observateur,
p.ScoEtudChangeAdr, p.UsersView,
p.ScoObservateur,
p.ScoUsersView,
p.ScoView, p.ScoView,
), ),
# Admin est le chef du département, pas le "super admin" # Admin est le chef du département, pas le "super admin"
# on doit donc lister toutes ses permissions: # on doit donc lister toutes ses permissions:
"Admin": ( "Admin": (
p.ScoAbsAddBillet, p.AbsAddBillet,
p.ScoAbsChange, p.AbsChange,
p.ScoChangeFormation, p.EditFormation,
p.ScoChangePreferences, p.EditPreferences,
p.ScoEditAllEvals, p.EditAllEvals,
p.ScoEditAllNotes, p.EditAllNotes,
p.ScoEditApo, p.EditApogee,
p.ScoEditFormationTags, p.EditFormationTags,
p.ScoEnsView, p.EnsView,
p.ScoEntrepriseChange, p.EtudAddAnnotations,
p.ScoEntrepriseView, p.EtudChangeAdr,
p.ScoEtudAddAnnotations, p.EtudChangeGroups,
p.ScoEtudChangeAdr, p.EtudInscrit,
p.ScoEtudChangeGroups, p.EditFormSemestre,
p.ScoEtudInscrit, p.Observateur,
p.ScoImplement, p.UsersAdmin,
p.ScoObservateur, p.UsersView,
p.ScoUsersAdmin,
p.ScoUsersView,
p.ScoView, p.ScoView,
), ),
# RespPE est le responsable poursuites d'études
# il peut ajouter des tags sur les formations:
# (doit avoir un rôle Ens en plus !)
"RespPe": (p.ScoEditFormationTags,),
# Rôles pour l'application relations entreprises # Rôles pour l'application relations entreprises
# ObservateurEntreprise est un observateur de l'application entreprise # ObservateurEntreprise est un observateur de l'application entreprise
"ObservateurEntreprise": (p.RelationsEntreprisesView,), "ObservateurEntreprise": (p.RelationsEntrepView,),
# UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification) # UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification)
"UtilisateurEntreprise": ( "UtilisateurEntreprise": (
p.RelationsEntreprisesView, p.RelationsEntrepView,
p.RelationsEntreprisesChange, p.RelationsEntrepEdit,
p.RelationsEntreprisesCorrespondants, p.RelationsEntrepViewCorrs,
), ),
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application) # AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
"AdminEntreprise": ( "AdminEntreprise": (
p.RelationsEntreprisesView, p.RelationsEntrepView,
p.RelationsEntreprisesChange, p.RelationsEntrepEdit,
p.RelationsEntreprisesExport, p.RelationsEntrepExport,
p.RelationsEntreprisesSend, p.RelationsEntrepSend,
p.RelationsEntreprisesValidate, p.RelationsEntrepValidate,
p.RelationsEntreprisesCorrespondants, p.RelationsEntrepViewCorrs,
), ),
# LecteurAPI peut utiliser l'API en lecture # LecteurAPI peut utiliser l'API en lecture
"LecteurAPI": (p.ScoView,), "LecteurAPI": (p.ScoView,),
"Observateur": (p.Observateur,),
# RespPE est le responsable poursuites d'études
# il peut ajouter des tags sur les formations:
# (doit avoir un rôle Ens en plus !)
"RespPe": (p.EditFormationTags,),
# Super Admin est un root: création/suppression de départements # Super Admin est un root: création/suppression de départements
# _tous_ les droits # _tous_ les droits
# Afin d'avoir tous les droits, il ne doit pas être asscoié à un département # Afin d'avoir tous les droits, il ne doit pas être asscoié à un département

View File

@ -92,7 +92,7 @@ def formsemestre_synchro_etuds(
sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem = sco_formsemestre.get_formsemestre(formsemestre_id)
sem["etape_apo_str"] = sco_formsemestre.formsemestre_etape_apo_str(sem) sem["etape_apo_str"] = sco_formsemestre.formsemestre_etape_apo_str(sem)
# Write access ? # Write access ?
if not current_user.has_permission(Permission.ScoEtudInscrit): if not current_user.has_permission(Permission.EtudInscrit):
read_only = True read_only = True
if read_only: if read_only:
submitted = False submitted = False

View File

@ -92,7 +92,7 @@ def external_ue_create(
log(f"creating external UE in {formsemestre}: {acronyme}") log(f"creating external UE in {formsemestre}: {acronyme}")
# Contrôle d'accès: # Contrôle d'accès:
if not current_user.has_permission(Permission.ScoImplement): if not current_user.has_permission(Permission.EditFormSemestre):
if (not formsemestre.resp_can_edit) or ( if (not formsemestre.resp_can_edit) or (
current_user.id not in [u.id for u in formsemestre.responsables] current_user.id not in [u.id for u in formsemestre.responsables]
): ):

View File

@ -56,7 +56,7 @@ def index_html(
H = [html_sco_header.html_sem_header("Gestion des utilisateurs")] H = [html_sco_header.html_sem_header("Gestion des utilisateurs")]
if current_user.has_permission(Permission.ScoUsersAdmin, g.scodoc_dept): if current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept):
H.append( H.append(
f"""<p><a href="{url_for("users.create_user_form", f"""<p><a href="{url_for("users.create_user_form",
scodoc_dept=g.scodoc_dept) scodoc_dept=g.scodoc_dept)
@ -118,7 +118,7 @@ def index_html(
fmt=fmt, fmt=fmt,
having_role=having_role, having_role=having_role,
with_inactives=with_inactives, with_inactives=with_inactives,
with_links=current_user.has_permission(Permission.ScoUsersAdmin, g.scodoc_dept), with_links=current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept),
) )
if fmt != "html": if fmt != "html":
return content return content

View File

@ -3,15 +3,51 @@
margin-bottom: 24px; margin-bottom: 24px;
} }
section#roles { .roles-editor {
background-color: #fffaf4; background-color: #fffaf4;
border-radius: 8px;
font-size: 90%;
margin-bottom: 24px;
padding: 8px;
} }
.role { .re-row {
/* align-items: center; */
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: nowrap;
gap: 4px; gap: 4px;
margin-bottom: 32px; margin-bottom: 8px;
}
.re-row-titres .role-standard {
font-weight: bold;
}
.re-row-perm {
transition: background-color 0.3s ease;
}
.re-row-perm:hover {
background-color: rgba(250, 250, 8, 0.816); /* Highlight color */
cursor: pointer;
}
.re-cell {
/* align-self: center; */
flex-basis: 40px;
flex-grow: 0;
flex-shrink: 0;
overflow-wrap: anywhere;
}
.permission-titre {
flex-basis: 210px;
flex-grow: 0;
flex-shrink: 0;
overflow-wrap: anywhere;
}
.role-titre {
transform: rotate(180deg) translate(60%, 0);
writing-mode: vertical-lr;
} }
.role>div, .role span { .role>div, .role span {
@ -26,8 +62,8 @@ section#roles {
} }
.role input:checked:not([value=aucun])+span { .role input:checked:not([value=aucun])+span {
background: rgb(165, 6, 59); background: rgb(0, 141, 42);
border-color: rgb(165, 6, 59); border-color: rgb(0, 141, 42);
color: #fff; color: #fff;
} }

View File

@ -42,7 +42,7 @@
<ul> <ul>
{% if ( {% if (
current_user.is_administrator() current_user.is_administrator()
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept) or current_user.has_permission(Permission.UsersAdmin, user.dept)
) %} ) %}
<li><a class="stdlink" href="{{ <li><a class="stdlink" href="{{
url_for( 'users.form_change_password', url_for( 'users.form_change_password',
@ -50,7 +50,7 @@
}}">modifier le mot de passe ou l'adresse mail</a> }}">modifier le mot de passe ou l'adresse mail</a>
</li> </li>
{% endif %} {% endif %}
{% if current_user.has_permission(Permission.ScoUsersAdmin, dept) %} {% if current_user.has_permission(Permission.UsersAdmin, dept) %}
<li><a class="stdlink" href="{{ <li><a class="stdlink" href="{{
url_for('users.create_user_form', scodoc_dept=g.scodoc_dept, url_for('users.create_user_form', scodoc_dept=g.scodoc_dept,
user_name=user.user_name, edit=1) user_name=user.user_name, edit=1)
@ -59,7 +59,7 @@
{% endif %} {% endif %}
{% if ( {% if (
current_user.is_administrator() current_user.is_administrator()
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept) or current_user.has_permission(Permission.UsersAdmin, user.dept)
) %} ) %}
<li><a class="stdlink" href="{{ <li><a class="stdlink" href="{{
url_for('users.toggle_active_user', scodoc_dept=g.scodoc_dept, url_for('users.toggle_active_user', scodoc_dept=g.scodoc_dept,
@ -96,7 +96,7 @@
</ul> </ul>
</div> </div>
{% if current_user.has_permission(Permission.ScoUsersAdmin, dept) %} {% if current_user.has_permission(Permission.UsersAdmin, dept) %}
<p><a class="stdlink" href=" <p><a class="stdlink" href="
{{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}} {{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}}
">Liste de tous les utilisateurs</a></p> ">Liste de tous les utilisateurs</a></p>

View File

@ -37,7 +37,7 @@
}}">Dept. {{ g.scodoc_dept }}</a></li> }}">Dept. {{ g.scodoc_dept }}</a></li>
{% endif %} {% endif %}
{% if not current_user.is_anonymous and {% if not current_user.is_anonymous and
current_user.has_permission(current_user.Permission.RelationsEntreprisesView, None) and scu and current_user.has_permission(current_user.Permission.RelationsEntrepView, None) and scu and
scu.is_entreprises_enabled() %} scu.is_entreprises_enabled() %}
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li> <li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
{% endif %} {% endif %}

View File

@ -8,7 +8,7 @@
{% macro menu_ue(niv, sem="pair", sem_idx=0) -%} {% macro menu_ue(niv, sem="pair", sem_idx=0) -%}
{% if niv['niveau'] %} {% if niv['niveau'] %}
{% if current_user.has_permission(sco.Permission.ScoChangeFormation) %} {% if current_user.has_permission(sco.Permission.EditFormation) %}
<select name="ue_niv_{{niv['niveau'].id}}" id="ue_niv_{{niv['niveau'].id}}" <select name="ue_niv_{{niv['niveau'].id}}" id="ue_niv_{{niv['niveau'].id}}"
onchange="assoc_ue_niveau(event, onchange="assoc_ue_niveau(event,
{{niv['niveau'].id}}, {{parcour.id}} {{niv['niveau'].id}}, {{parcour.id}}

View File

@ -24,7 +24,7 @@
{% endif %} {% endif %}
</div> </div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<div class="parent-btn"> <div class="parent-btn">
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_correspondant', entreprise_id=correspondant.site.entreprise.id, site_id=correspondant.site_id, correspondant_id=correspondant.id) }}">Modifier correspondant</a> <a class="btn btn-primary" href="{{ url_for('entreprises.edit_correspondant', entreprise_id=correspondant.site.entreprise.id, site_id=correspondant.site_id, correspondant_id=correspondant.id) }}">Modifier correspondant</a>
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_correspondant', entreprise_id=correspondant.site.entreprise.id, site_id=correspondant.site_id, correspondant_id=correspondant.id) }}">Supprimer correspondant</a> <a class="btn btn-danger" href="{{ url_for('entreprises.delete_correspondant', entreprise_id=correspondant.site.entreprise.id, site_id=correspondant.site_id, correspondant_id=correspondant.id) }}">Supprimer correspondant</a>

View File

@ -22,28 +22,28 @@
{% for filedir, filename in files %} {% for filedir, filename in files %}
<a href="{{ url_for('entreprises.get_offre_file', entreprise_id=entreprise.id, offre_id=offre.id, filedir=filedir, filename=filename )}}">{{ filename }}</a> <a href="{{ url_for('entreprises.get_offre_file', entreprise_id=entreprise.id, offre_id=offre.id, filedir=filedir, filename=filename )}}">{{ filename }}</a>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a href="{{ url_for('entreprises.delete_offre_file', entreprise_id=entreprise.id, offre_id=offre.id, filedir=filedir )}}" style="margin-left: 5px;"><img title="Supprimer fichier" alt="supprimer" width="10" height="9" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a> <a href="{{ url_for('entreprises.delete_offre_file', entreprise_id=entreprise.id, offre_id=offre.id, filedir=filedir )}}" style="margin-left: 5px;"><img title="Supprimer fichier" alt="supprimer" width="10" height="9" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a>
{% endif %} {% endif %}
<br> <br>
{% endfor %} {% endfor %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a href="{{ url_for('entreprises.add_offre_file', entreprise_id=entreprise.id, offre_id=offre.id) }}">Ajoutez un fichier</a> <a href="{{ url_for('entreprises.add_offre_file', entreprise_id=entreprise.id, offre_id=offre.id) }}">Ajoutez un fichier</a>
{% endif %} {% endif %}
</div> </div>
<div class="parent-btn"> <div class="parent-btn">
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_offre', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Modifier l'offre</a> <a class="btn btn-primary" href="{{ url_for('entreprises.edit_offre', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Modifier l'offre</a>
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_offre', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Supprimer l'offre</a> <a class="btn btn-danger" href="{{ url_for('entreprises.delete_offre', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Supprimer l'offre</a>
{% endif %} {% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesSend, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepSend, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.envoyer_offre', entreprise_id=entreprise.id, offre_id=offre.id) }}">Envoyer l'offre</a> <a class="btn btn-primary" href="{{ url_for('entreprises.envoyer_offre', entreprise_id=entreprise.id, offre_id=offre.id) }}">Envoyer l'offre</a>
{% endif %} {% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
{% if not offre.expired %} {% if not offre.expired %}
<a class="btn btn-danger" href="{{ url_for('entreprises.expired', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Rendre expirée</a> <a class="btn btn-danger" href="{{ url_for('entreprises.expired', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Rendre expirée</a>
{% else %} {% else %}

View File

@ -26,7 +26,7 @@
<div class="container" style="margin-bottom: 10px;"> <div class="container" style="margin-bottom: 10px;">
<h1>Liste des contacts</h1> <h1>Liste des contacts</h1>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a class="btn btn-primary" style="margin-bottom:10px;" <a class="btn btn-primary" style="margin-bottom:10px;"
href="{{ url_for('entreprises.add_contact', entreprise_id=entreprise.id) }}">Ajouter contact</a> href="{{ url_for('entreprises.add_contact', entreprise_id=entreprise.id) }}">Ajouter contact</a>
{% endif %} {% endif %}
@ -36,7 +36,7 @@
<td data-priority="">Date</td> <td data-priority="">Date</td>
<td data-priority="">Utilisateur</td> <td data-priority="">Utilisateur</td>
<td data-priority="">Notes</td> <td data-priority="">Notes</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td data-priority="">Action</td> <td data-priority="">Action</td>
{% endif %} {% endif %}
</tr> </tr>
@ -47,7 +47,7 @@
<td>{{ contact.date.strftime('%d/%m/%Y %Hh%M') }}</td> <td>{{ contact.date.strftime('%d/%m/%Y %Hh%M') }}</td>
<td>{{ contact.user|get_nomcomplet_by_id }}</td> <td>{{ contact.user|get_nomcomplet_by_id }}</td>
<td>{{ contact.notes }}</td> <td>{{ contact.notes }}</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td> <td>
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
@ -71,7 +71,7 @@
<td>Date</td> <td>Date</td>
<td>Utilisateur</td> <td>Utilisateur</td>
<td>Notes</td> <td>Notes</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td>Action</td> <td>Action</td>
{% endif %} {% endif %}
</tr> </tr>

View File

@ -24,13 +24,13 @@
{% endif %} {% endif %}
<div class="container boutons"> <div class="container boutons">
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a> <a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a>
{% endif %} {% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepExport, None) %}
<a class="btn btn-default" href="{{ url_for('entreprises.import_donnees') }}">Importer des données</a> <a class="btn btn-default" href="{{ url_for('entreprises.import_donnees') }}">Importer des données</a>
{% endif %} {% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) and entreprises %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepExport, None) and entreprises %}
<a class="btn btn-default" href="{{ url_for('entreprises.export_donnees') }}">Exporter des données</a> <a class="btn btn-default" href="{{ url_for('entreprises.export_donnees') }}">Exporter des données</a>
{% endif %} {% endif %}
</div> </div>
@ -57,7 +57,7 @@
<td data-priority="6">Code postal</td> <td data-priority="6">Code postal</td>
<td data-priority="5">Ville</td> <td data-priority="5">Ville</td>
<td data-priority="7">Pays</td> <td data-priority="7">Pays</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td data-priority="3">Action</td> <td data-priority="3">Action</td>
{% endif %} {% endif %}
</tr> </tr>
@ -73,7 +73,7 @@
<td>{{ entreprise.codepostal }}</td> <td>{{ entreprise.codepostal }}</td>
<td>{{ entreprise.ville }}</td> <td>{{ entreprise.ville }}</td>
<td>{{ entreprise.pays }}</td> <td>{{ entreprise.pays }}</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td> <td>
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
@ -105,7 +105,7 @@
<td>Code postal</td> <td>Code postal</td>
<td>Ville</td> <td>Ville</td>
<td>Pays</td> <td>Pays</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td>Action</td> <td>Action</td>
{% endif %} {% endif %}
</tr> </tr>

View File

@ -60,7 +60,7 @@
{% endif %} {% endif %}
</div> </div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<div> <div>
Taxe d'apprentissage<br> Taxe d'apprentissage<br>
<a class="btn btn-primary" <a class="btn btn-primary"
@ -90,7 +90,7 @@
</div> </div>
<div> <div>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a class="btn btn-primary" <a class="btn btn-primary"
href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a> href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a>
{% if entreprise.active %} {% if entreprise.active %}
@ -123,7 +123,7 @@
Code postal : {{ site.codepostal }}<br> Code postal : {{ site.codepostal }}<br>
Ville : {{ site.ville }}<br> Ville : {{ site.ville }}<br>
Pays : {{ site.pays }} Pays : {{ site.pays }}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<div> <div>
<a class="btn btn-primary" <a class="btn btn-primary"
href="{{ url_for('entreprises.edit_site', entreprise_id=entreprise.id, site_id=site.id) }}">Modifier</a> href="{{ url_for('entreprises.edit_site', entreprise_id=entreprise.id, site_id=site.id) }}">Modifier</a>
@ -132,7 +132,7 @@
correspondant</a> correspondant</a>
</div> </div>
{% endif %} {% endif %}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepViewCorrs, None) %}
{% for correspondant in site.correspondants %} {% for correspondant in site.correspondants %}
{% include 'entreprises/_correspondant.j2' %} {% include 'entreprises/_correspondant.j2' %}
{% endfor %} {% endfor %}
@ -156,7 +156,7 @@
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3> <h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', entreprise_id=entreprise.id) }}" <a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', entreprise_id=entreprise.id) }}"
style="margin-bottom:10px;">Ajouter stage ou apprentissage</a> style="margin-bottom:10px;">Ajouter stage ou apprentissage</a>
{% endif %} {% endif %}
@ -170,7 +170,7 @@
<td data-priority="1">Étudiant</td> <td data-priority="1">Étudiant</td>
<td data-priority="6">Formation</td> <td data-priority="6">Formation</td>
<td data-priority="7">Notes</td> <td data-priority="7">Notes</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td data-priority="3">Action</td> <td data-priority="3">Action</td>
{% endif %} {% endif %}
</tr> </tr>
@ -187,7 +187,7 @@
etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td> etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td>
<td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</td> <td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</td>
<td>{{ stage_apprentissage.notes }}</td> <td>{{ stage_apprentissage.notes }}</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td> <td>
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
@ -215,7 +215,7 @@
<td>Étudiant</td> <td>Étudiant</td>
<td>Formation</td> <td>Formation</td>
<td>Notes</td> <td>Notes</td>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %}
<td>Action</td> <td>Action</td>
{% endif %} {% endif %}
</tr> </tr>

View File

@ -41,7 +41,7 @@
Code postal : {{ site.codepostal }}<br> Code postal : {{ site.codepostal }}<br>
Ville : {{ site.ville }}<br> Ville : {{ site.ville }}<br>
Pays : {{ site.pays }} Pays : {{ site.pays }}
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepViewCorrs, None) %}
{% for correspondant in site.correspondants %} {% for correspondant in site.correspondants %}
<div class="correspondant"> <div class="correspondant">
<div> <div>

View File

@ -6,7 +6,7 @@
<a href="{{ url_for('entreprises.index') }}" class="nav_entreprise_link {% if title=='Entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises</a> <a href="{{ url_for('entreprises.index') }}" class="nav_entreprise_link {% if title=='Entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises</a>
</li> </li>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepViewCorrs, None) %}
<li class="nav_entreprise_item"> <li class="nav_entreprise_item">
<a href="{{ url_for('entreprises.correspondants') }}" class="nav_entreprise_link {% if title=='Correspondants' %}nav_entreprise_link-active{% endif %}">Correspondants</a> <a href="{{ url_for('entreprises.correspondants') }}" class="nav_entreprise_link {% if title=='Correspondants' %}nav_entreprise_link-active{% endif %}">Correspondants</a>
</li> </li>
@ -16,7 +16,7 @@
<a href="{{ url_for('entreprises.offres_recues') }}" class="nav_entreprise_link {% if title=='Offres reçues' %}nav_entreprise_link-active{% endif %}">Offres reçues</a> <a href="{{ url_for('entreprises.offres_recues') }}" class="nav_entreprise_link {% if title=='Offres reçues' %}nav_entreprise_link-active{% endif %}">Offres reçues</a>
</li> </li>
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesValidate, None) %} {% if current_user.has_permission(current_user.Permission.RelationsEntrepValidate, None) %}
<li class="nav_entreprise_item"> <li class="nav_entreprise_item">
<a href="{{ url_for('entreprises.validation') }}" class="nav_entreprise_link {% if title=='Validation entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises à valider</a> <a href="{{ url_for('entreprises.validation') }}" class="nav_entreprise_link {% if title=='Validation entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises à valider</a>
</li> </li>

View File

@ -5,7 +5,7 @@
{% block app_content %} {% block app_content %}
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<br> <br>
<div>{{ info_message }}</div> <div>{{ info_message | safe }}</div>
<br> <br>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">

View File

@ -39,7 +39,7 @@
<li><a href="ScoDoc/RT/Scolarite/Notes/essai"><tt>Notes/essai</tt> : test "notes", url <li><a href="ScoDoc/RT/Scolarite/Notes/essai"><tt>Notes/essai</tt> : test "notes", url
manuelle</a></li> manuelle</a></li>
<li><a href="{{ url_for('notes.essai2' , scodoc_dept='RT') }}"><tt>Notes/essai2</tt></a> : permission <li><a href="{{ url_for('notes.essai2' , scodoc_dept='RT') }}"><tt>Notes/essai2</tt></a> : permission
ScoImplement dans RT EditFormSemestre dans RT
</li> </li>
</ul> </ul>
<h3>Essais décorateurs et appels</h3> <h3>Essais décorateurs et appels</h3>

View File

@ -1,69 +0,0 @@
{# -*- mode: jinja-html -*- #}
{# -*- Edition des rôles/permissions -- inspiré de partition_editor -*- #}
{% extends "base.j2" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block styles %}
{{super()}}
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/partition_editor.css">
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/role_editor.css">
{% endblock %}
{% block app_content %}
<h1>Définition des rôles et leurs permissions</h1>
<div class="help">Les rôles sont associés à un ensemble de permissions. Chaque
utilisateur peut avoir un nombre quelconque de rôles <em>dans chaque
département</em>.
Sur cette page vous pouvez modifier les permissions associée à chaque rôle, ou créer de nouveaux rôles.
</div>
{# <div class="links">
<a class="stdlink" href="{{ url_for('scodoc.users') }}">liste des comptes utilisateurs</a>
</div> #}
<main>
<section id="roles">
<div class="permission-roles">
{% for role in roles %}
<div class="role">
<div>{{role.name}}</div>
<label title="Aucune permission">
<input type="checkbox" name="{{role.id}}" value="aucun" checked="" class="">
<span class="aucun"> - </span>
</label>
{% for permission_name in permissions_names %}
<label>
<input type="checkbox"
name="{{role.id}}-{{Permission.get_by_name(permission_name)}}"
value="{{role.id}}-{{Permission.get_by_name(permission_name)}}"
{{"checked" if role.has_permission(Permission.get_by_name(permission_name)) else ''}}
>
<span data-permission="{{
Permission.get_by_name(permission_name)
}}">{{permission_name}}</span>
</label>
{% endfor %}
</div>
{% endfor %}
</div>
</section>
</main>
<script>
function associe_role_permission() {
alert("toto");
}
document.querySelectorAll("label").forEach(btn => {
btn.addEventListener("mousedown", (event) => { event.preventDefault() })
});
document.querySelectorAll(".role input").forEach(input => {
input.addEventListener("input", associe_role_permission)
});
</script>
{% endblock %}

View File

@ -7,13 +7,15 @@
{{ exc | safe }} {{ exc | safe }}
<p> <div style="margin-top: 16px;">
{% if g.scodoc_dept %} {% if g.scodoc_dept %}
<a href="{{ exc.dest_url or url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}">continuer</a> <a href="{{ exc.dest_url or url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}">continuer</a>
{% elif exc.dest_url %}
<a href="{{ exc.dest_url or url_for('scodoc.index') }}">continuer</a>
{% else %} {% else %}
<a href="{{ exc.dest_url or url_for('scodoc.index') }}">retour page d'accueil</a> <a href="{{ exc.dest_url or url_for('scodoc.index') }}">retour page d'accueil</a>
{% endif %} {% endif %}
</p> </div>
<p style="margin-top: 32px;" class="help"> <p style="margin-top: 32px;" class="help">
Si le problème persiste, merci de contacter le support ScoDoc via Si le problème persiste, merci de contacter le support ScoDoc via

View File

@ -0,0 +1,33 @@
{% extends "base.j2" %}
{% block styles %}
{{super()}}
<style>
.permission-info {
border-radius: 8px;
background-color: #fffaf4;
margin-bottom: 24px;
padding: 8px;
}
</style>
{% endblock %}
{% block app_content %}
<h1>Définition des rôles et leurs permissions</h1>
<div class="permission-info">
<h2>Détails sur la permission {{permission_name}}</h2>
<div class="permission-details">
<div><b>Code de la permission :</b> <tt>{{permission_name}} ({{permission}})</tt></div>
<div><b>Description :</b> <em>{{Permission.description[permission_name]}}</em></div>
</div>
</div>
<div><a class="stdlink" href="{{url_for( 'scodoc.config_roles' )}}">Formulaire d'édition des rôles</a></div>
{% endblock %}

View File

@ -0,0 +1,22 @@
{# -*- mode: jinja-html -*- #}
{% extends "base.j2" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h1>Créer un rôle</h1>
<div class="help">
Un rôle est associé à un ensemble de permissions.
Les utilisateurs peuvent avoir un ou plusieurs rôles dans chaque département.
</div>
<div><b>Rôles déjà existants :</b> <tt>{{', '.join(roles_names)}}</tt>
<div class="row" style="margin-top: 24px;">
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,112 @@
{# -*- mode: jinja-html -*- #}
{# -*- Edition des rôles/permissions -*- #}
{% extends "base.j2" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block styles %}
{{super()}}
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/role_editor.css">
{% endblock %}
{% block app_content %}
<h1>Définition des rôles et leurs permissions</h1>
<div class="help">Les rôles sont associés à un ensemble de permissions. Chaque
utilisateur peut avoir un nombre quelconque de rôles <em>dans chaque
département</em>.
Sur cette page vous pouvez modifier les permissions associée à chaque rôle, ou créer de nouveaux rôles.
Les rôles <b>en gras</b> sont les rôles standards de ScoDoc.
</div>
{# <div class="links">
<a class="stdlink" href="{{ url_for('scodoc.users') }}">liste des comptes utilisateurs</a>
</div> #}
<main class="roles-editor">
<div class="re-row re-row-titres">
<div class="re-cell role-titre permission-titre"></div>
{% for role in roles %}
<div class="re-cell role-titre {{'role-standard' if role.name in SCO_ROLES_DEFAULTS else ''}}">
<a class="discretelink" href="{{
url_for('scodoc.role_info', role_name=role.name)
}}">{{role.name}}</a>
</div>
{% endfor %}
</div>
{% for permission_name in permissions_names %}
<div class="re-row re-row-perm">
<div class="re-cell permission-titre" style="position: relative;">
<div class="with_scoplement">
<div><a class="discretelink" href="{{
url_for('scodoc.permission_info', perm_name=permission_name)
}}">{{permission_name}}</a></div>
<div class="scoplement">
{{ Permission.description.get(permission_name) }}
</div>
</div>
</div>
{% for role in roles %}
<div class="re-cell {{'role-standard' if role.name in SCO_ROLES_DEFAULTS else ''}}">
<label>
<input type="checkbox"
name="{{role.id}}-{{Permission.get_by_name(permission_name)}}"
data-role="{{role.name}}"
data-permission="{{permission_name}}"
{{'checked' if role.has_permission(Permission.get_by_name(permission_name)) else ''}}
>
</label>
</div>
{% endfor %}
</div>
{% endfor %}
</main>
<div>
<a class="stdlink" href="{{url_for('scodoc.role_create')}}">Créer un nouveau rôle</a>
</div>
<div style="margin-top: 16px;">
🛟 <a class="stdlink" href="{{url_for('auth.reset_standard_roles_permissions')}}">Remettre
les permissions des rôles standards à leurs valeurs par défaut</a>
<em>(efface les modifications apportées aux rôles <tt>{{ ', '.join(SCO_ROLES_DEFAULTS.keys()) }}</tt>)</em>
</div>
<script>
async function associe_role_permission(event) {
// /role/<string:role_name>/add_permission/<string:perm_name>"
const method = event.target.checked ? "/add_permission/" : "/remove_permission/";
const url = `${SCO_URL}/../api/role/${event.target.dataset.role}${method}${event.target.dataset.permission}`;
try {
const response = await fetch(
url,
{
method: "POST",
}
);
const data = await response.json();
if (data.role_name != event.target.dataset.role) {
console.error("Fetch error, received:", data);
alert("Une erreur est survenue");
location.reload();
}
sco_message(`rôle ${event.target.dataset.role} enregistré`);
} catch (error) {
console.error("Fetch error:", error);
sco_message("Erreur réseau: valeur non enregistrée");
}
}
document.querySelectorAll("label").forEach(btn => {
btn.addEventListener("mousedown", (event) => { event.preventDefault() })
});
document.querySelectorAll(".re-cell input").forEach(input => {
input.addEventListener("input", associe_role_permission)
});
</script>
{% endblock %}

View File

@ -0,0 +1,46 @@
{# -*- mode: jinja-html -*- #}
{# -*- Info sur un rôle -*- #}
{% extends "base.j2" %}
{% block styles %}
{{super()}}
<style>
.role-info {
border-radius: 8px;
background-color: #fffaf4;
margin-bottom: 24px;
padding: 8px;
}
.role-details {
margin-bottom: 16px;
}
</style>
{% endblock %}
{% block app_content %}
<h1>Définition des rôles et leurs permissions</h1>
<div class="role-info">
<h2>Détails sur le rôle {{role.name}}</h2>
<div class="role-details">
<div><b>Code du rôle :</b> <tt>{{role.name}}</tt></div>
<div><b>Permissions associées :</b> <tt>{{', '.join(role.get_named_permissions())}}</tt></div>
</div>
</div>
<div>
{% if role.name in SCO_ROLES_DEFAULTS %}
<em>Ce rôle fait partie des rôles standards de ScoDoc et ne peut pas être supprimé.</em>
{% else %}
❌ <a class="stdlink" href="{{url_for('scodoc.role_delete', role_name=role.name )}}">supprimer ce rôle</a>
{% endif %}
</div>
<div style="margin-top: 24px;"><a class="stdlink" href="{{url_for( 'scodoc.config_roles' )}}">Formulaire d'édition des rôles</a></div>
{% endblock %}

View File

@ -25,16 +25,16 @@
<a href="{{url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Semestres</a> <br> <a href="{{url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Semestres</a> <br>
<a href="{{url_for('notes.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Programmes</a> <br> <a href="{{url_for('notes.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Programmes</a> <br>
{% if current_user.has_permission(sco.Permission.ScoAbsChange)%} {% if current_user.has_permission(sco.Permission.AbsChange)%}
<a href="{{url_for('assiduites.bilan_dept', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Assiduité</a> <br> <a href="{{url_for('assiduites.bilan_dept', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Assiduité</a> <br>
{% endif %} {% endif %}
{% if current_user.has_permission(sco.Permission.ScoUsersAdmin) {% if current_user.has_permission(sco.Permission.UsersAdmin)
or current_user.has_permission(sco.Permission.ScoUsersView) or current_user.has_permission(sco.Permission.UsersView)
%} %}
<a href="{{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Utilisateurs</a> <br /> <a href="{{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Utilisateurs</a> <br />
{% endif %} {% endif %}
{% if current_user.has_permission(sco.Permission.ScoChangePreferences) %} {% if current_user.has_permission(sco.Permission.EditPreferences) %}
<a href="{{url_for('scolar.edit_preferences', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Paramétrage</a> <br> <a href="{{url_for('scolar.edit_preferences', scodoc_dept=g.scodoc_dept)}}" class="sidebar">Paramétrage</a> <br>
{% endif %} {% endif %}
{# /sidebar_common #} {# /sidebar_common #}
@ -61,7 +61,7 @@
<br />{{sco.nbabsjust}} J., {{sco.nbabsnj}} N.J.</span> <br />{{sco.nbabsjust}} J., {{sco.nbabsnj}} N.J.</span>
{% endif %} {% endif %}
<ul> <ul>
{% if current_user.has_permission(sco.Permission.ScoAbsChange) %} {% if current_user.has_permission(sco.Permission.AbsChange) %}
<li><a href="{{ url_for('assiduites.signal_assiduites_etud', scodoc_dept=g.scodoc_dept, <li><a href="{{ url_for('assiduites.signal_assiduites_etud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Ajouter</a></li> etudid=sco.etud.id) }}">Ajouter</a></li>
<li><a href="{{ url_for('assiduites.ajout_justificatif_etud', scodoc_dept=g.scodoc_dept, <li><a href="{{ url_for('assiduites.ajout_justificatif_etud', scodoc_dept=g.scodoc_dept,

View File

@ -83,7 +83,7 @@ def index_html():
), ),
] ]
if current_user.has_permission( if current_user.has_permission(
Permission.ScoAbsChange Permission.AbsChange
) and sco_preferences.get_preference("handle_billets_abs"): ) and sco_preferences.get_preference("handle_billets_abs"):
H.append( H.append(
f""" f"""
@ -100,7 +100,7 @@ def index_html():
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail) # ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
@bp.route("/AddBilletAbsence", methods=["GET", "POST"]) # API ScoDoc 7 compat @bp.route("/AddBilletAbsence", methods=["GET", "POST"]) # API ScoDoc 7 compat
@scodoc @scodoc
@permission_required_compat_scodoc7(Permission.ScoAbsAddBillet) @permission_required_compat_scodoc7(Permission.AbsAddBillet)
@scodoc7func @scodoc7func
def AddBilletAbsence( def AddBilletAbsence(
begin, begin,
@ -152,7 +152,7 @@ def AddBilletAbsence(
@bp.route("/add_billets_absence_form", methods=["GET", "POST"]) @bp.route("/add_billets_absence_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoAbsAddBillet) @permission_required(Permission.AbsAddBillet)
@scodoc7func @scodoc7func
def add_billets_absence_form(etudid): def add_billets_absence_form(etudid):
"""Formulaire ajout billet (pour tests seulement, le vrai """Formulaire ajout billet (pour tests seulement, le vrai
@ -272,7 +272,7 @@ def list_billets():
@bp.route("/delete_billets_absence", methods=["POST", "GET"]) @bp.route("/delete_billets_absence", methods=["POST", "GET"])
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
@scodoc7func @scodoc7func
def delete_billets_absence(billet_id, dialog_confirmed=False): def delete_billets_absence(billet_id, dialog_confirmed=False):
"""Supprime un billet.""" """Supprime un billet."""
@ -333,7 +333,7 @@ def _ProcessBilletAbsence(
@bp.route("/process_billet_absence_form", methods=["POST", "GET"]) @bp.route("/process_billet_absence_form", methods=["POST", "GET"])
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
@scodoc7func @scodoc7func
def process_billet_absence_form(billet_id: int): def process_billet_absence_form(billet_id: int):
"""Formulaire traitement d'un billet""" """Formulaire traitement d'un billet"""

View File

@ -157,7 +157,7 @@ class HTMLBuilder:
@bp.route("/") @bp.route("/")
@bp.route("/BilanDept") @bp.route("/BilanDept")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def bilan_dept(): def bilan_dept():
"""Gestionnaire assiduités, page principale""" """Gestionnaire assiduités, page principale"""
H = [ H = [
@ -185,7 +185,7 @@ def bilan_dept():
) )
H.append(sco_find_etud.form_search_etud(dest_url="assiduites.bilan_etud")) H.append(sco_find_etud.form_search_etud(dest_url="assiduites.bilan_etud"))
if current_user.has_permission( if current_user.has_permission(
Permission.ScoAbsChange Permission.AbsChange
) and sco_preferences.get_preference("handle_billets_abs"): ) and sco_preferences.get_preference("handle_billets_abs"):
H.append( H.append(
f""" f"""
@ -275,7 +275,7 @@ def bilan_dept():
@bp.route("/SignaleAssiduiteEtud") @bp.route("/SignaleAssiduiteEtud")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def signal_assiduites_etud(): def signal_assiduites_etud():
""" """
signal_assiduites_etud Saisie de l'assiduité d'un étudiant signal_assiduites_etud Saisie de l'assiduité d'un étudiant
@ -477,7 +477,7 @@ def bilan_etud():
@bp.route("/AjoutJustificatifEtud") @bp.route("/AjoutJustificatifEtud")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def ajout_justificatif_etud(): def ajout_justificatif_etud():
""" """
ajout_justificatif_etud : Affichage et création/modification des justificatifs de l'étudiant ajout_justificatif_etud : Affichage et création/modification des justificatifs de l'étudiant
@ -579,7 +579,7 @@ def calendrier_etud():
@bp.route("/SignalAssiduiteGr") @bp.route("/SignalAssiduiteGr")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def signal_assiduites_group(): def signal_assiduites_group():
""" """
signal_assiduites_group Saisie des assiduités des groupes pour le jour donnée signal_assiduites_group Saisie des assiduités des groupes pour le jour donnée
@ -1016,7 +1016,7 @@ def visu_assi_group():
@bp.route("/SignalAssiduiteDifferee") @bp.route("/SignalAssiduiteDifferee")
@scodoc @scodoc
@permission_required(Permission.ScoAbsChange) @permission_required(Permission.AbsChange)
def signal_assiduites_diff(): def signal_assiduites_diff():
group_ids: list[int] = request.args.get("group_ids", None) group_ids: list[int] = request.args.get("group_ids", None)
formsemestre_id: int = request.args.get("formsemestre_id", -1) formsemestre_id: int = request.args.get("formsemestre_id", -1)

View File

@ -120,7 +120,7 @@ def validation_rcues(
@bp.route("/ue_parcours_ects/<int:ue_id>", methods=["GET", "POST"]) @bp.route("/ue_parcours_ects/<int:ue_id>", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def ue_parcours_ects(ue_id: int): def ue_parcours_ects(ue_id: int):
"""formulaire (div) pour associer des ECTS par parcours d'une UE""" """formulaire (div) pour associer des ECTS par parcours d'une UE"""
ue: UniteEns = ( ue: UniteEns = (

View File

@ -185,7 +185,7 @@ sco_publish(
sco_publish( sco_publish(
"/formsemestre_createwithmodules", "/formsemestre_createwithmodules",
sco_formsemestre_edit.formsemestre_createwithmodules, sco_formsemestre_edit.formsemestre_createwithmodules,
Permission.ScoImplement, Permission.EditFormSemestre,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@ -200,25 +200,25 @@ sco_publish(
sco_publish( sco_publish(
"/formsemestre_clone", "/formsemestre_clone",
sco_formsemestre_edit.formsemestre_clone, sco_formsemestre_edit.formsemestre_clone,
Permission.ScoImplement, Permission.EditFormSemestre,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/formsemestre_associate_new_version", "/formsemestre_associate_new_version",
sco_formation_versions.formsemestre_associate_new_version, sco_formation_versions.formsemestre_associate_new_version,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/formsemestre_delete", "/formsemestre_delete",
sco_formsemestre_edit.formsemestre_delete, sco_formsemestre_edit.formsemestre_delete,
Permission.ScoImplement, Permission.EditFormSemestre,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/formsemestre_delete2", "/formsemestre_delete2",
sco_formsemestre_edit.formsemestre_delete2, sco_formsemestre_edit.formsemestre_delete2,
Permission.ScoImplement, Permission.EditFormSemestre,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
@ -240,7 +240,7 @@ sco_publish(
sco_publish( sco_publish(
"/formsemestres_bulletins", "/formsemestres_bulletins",
sco_recapcomplet.formsemestres_bulletins, sco_recapcomplet.formsemestres_bulletins,
Permission.ScoObservateur, Permission.Observateur,
) )
sco_publish( sco_publish(
"/moduleimpl_status", sco_moduleimpl_status.moduleimpl_status, Permission.ScoView "/moduleimpl_status", sco_moduleimpl_status.moduleimpl_status, Permission.ScoView
@ -254,19 +254,19 @@ sco_publish(
sco_publish( sco_publish(
"/formation_create", "/formation_create",
sco_edit_formation.formation_create, sco_edit_formation.formation_create,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/formation_delete", "/formation_delete",
sco_edit_formation.formation_delete, sco_edit_formation.formation_delete,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/formation_edit", "/formation_edit",
sco_edit_formation.formation_edit, sco_edit_formation.formation_edit,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@ -332,7 +332,7 @@ def formsemestre_bulletinetud(
version=version, version=version,
), ),
can_edit_appreciations=formsemestre.est_responsable(current_user) can_edit_appreciations=formsemestre.est_responsable(current_user)
or (current_user.has_permission(Permission.ScoEtudInscrit)), or (current_user.has_permission(Permission.EtudInscrit)),
etud=etud, etud=etud,
formsemestre=formsemestre, formsemestre=formsemestre,
inscription_courante=etud.inscription_courante(), inscription_courante=etud.inscription_courante(),
@ -429,26 +429,26 @@ sco_publish(
sco_publish( sco_publish(
"/ue_create", "/ue_create",
sco_edit_ue.ue_create, sco_edit_ue.ue_create,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/ue_delete", "/ue_delete",
sco_edit_ue.ue_delete, sco_edit_ue.ue_delete,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/ue_edit", "/ue_edit",
sco_edit_ue.ue_edit, sco_edit_ue.ue_edit,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@bp.route("/set_ue_niveau_competence", methods=["POST"]) @bp.route("/set_ue_niveau_competence", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def set_ue_niveau_competence(): def set_ue_niveau_competence():
"""Associe UE et niveau. """Associe UE et niveau.
Si le niveau_id est "", désassocie.""" Si le niveau_id est "", désassocie."""
@ -501,7 +501,7 @@ def ue_infos(ue_id):
@bp.route("/ue_set_internal", methods=["GET", "POST"]) @bp.route("/ue_set_internal", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
@scodoc7func @scodoc7func
def ue_set_internal(ue_id): def ue_set_internal(ue_id):
"""""" """"""
@ -541,7 +541,7 @@ def ue_sharing_code():
sco_publish( sco_publish(
"/edit_ue_set_code_apogee", "/edit_ue_set_code_apogee",
sco_edit_ue.edit_ue_set_code_apogee, sco_edit_ue.edit_ue_set_code_apogee,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["POST"], methods=["POST"],
) )
sco_publish( sco_publish(
@ -568,48 +568,48 @@ sco_publish(
sco_publish( sco_publish(
"/formation_add_malus_modules", "/formation_add_malus_modules",
sco_edit_module.formation_add_malus_modules, sco_edit_module.formation_add_malus_modules,
Permission.ScoChangeFormation, Permission.EditFormation,
) )
sco_publish( sco_publish(
"/matiere_create", "/matiere_create",
sco_edit_matiere.matiere_create, sco_edit_matiere.matiere_create,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/matiere_delete", "/matiere_delete",
sco_edit_matiere.matiere_delete, sco_edit_matiere.matiere_delete,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/matiere_edit", "/matiere_edit",
sco_edit_matiere.matiere_edit, sco_edit_matiere.matiere_edit,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/module_create", "/module_create",
sco_edit_module.module_create, sco_edit_module.module_create,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/module_delete", "/module_delete",
sco_edit_module.module_delete, sco_edit_module.module_delete,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/module_edit", "/module_edit",
sco_edit_module.module_edit, sco_edit_module.module_edit,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/edit_module_set_code_apogee", "/edit_module_set_code_apogee",
sco_edit_module.edit_module_set_code_apogee, sco_edit_module.edit_module_set_code_apogee,
Permission.ScoChangeFormation, Permission.EditFormation,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish("/module_list", sco_edit_module.module_table, Permission.ScoView) sco_publish("/module_list", sco_edit_module.module_table, Permission.ScoView)
@ -618,7 +618,7 @@ sco_publish("/module_tag_search", sco_tag_module.module_tag_search, Permission.S
@bp.route("/module_tag_set", methods=["POST"]) @bp.route("/module_tag_set", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditFormationTags) @permission_required(Permission.EditFormationTags)
def module_tag_set(): def module_tag_set():
"""Set tags on module""" """Set tags on module"""
module_id = int(request.form.get("module_id")) module_id = int(request.form.get("module_id"))
@ -628,7 +628,7 @@ def module_tag_set():
@bp.route("/module_clone", methods=["POST"]) @bp.route("/module_clone", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def module_clone(): def module_clone():
"""Clone existing module""" """Clone existing module"""
module_id = int(request.form.get("module_id")) module_id = int(request.form.get("module_id"))
@ -656,7 +656,7 @@ def module_clone():
def index_html(): def index_html():
"Page accueil formations" "Page accueil formations"
editable = current_user.has_permission(Permission.ScoChangeFormation) editable = current_user.has_permission(Permission.EditFormation)
H = [ H = [
html_sco_header.sco_header(page_title="Programmes formations"), html_sco_header.sco_header(page_title="Programmes formations"),
@ -735,7 +735,7 @@ def formation_export(formation_id, export_ids=False, fmt=None, export_codes_apo=
@bp.route("/formation_import_xml_form", methods=["GET", "POST"]) @bp.route("/formation_import_xml_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
@scodoc7func @scodoc7func
def formation_import_xml_form(): def formation_import_xml_form():
"form import d'une formation en XML" "form import d'une formation en XML"
@ -790,7 +790,7 @@ def formation_import_xml_form():
# sco_publish( # sco_publish(
# "/formation_create_new_version", # "/formation_create_new_version",
# sco_formations.formation_create_new_version, # sco_formations.formation_create_new_version,
# Permission.ScoChangeFormation, # Permission.EditFormation,
# ) # )
# --- UE # --- UE
@ -800,15 +800,13 @@ sco_publish(
Permission.ScoView, Permission.ScoView,
) )
sco_publish( sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
"/module_move", sco_edit_formation.module_move, Permission.ScoChangeFormation sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.EditFormation)
)
sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormation)
@bp.route("/ue_clone", methods=["POST"]) @bp.route("/ue_clone", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def ue_clone(): def ue_clone():
"""Clone existing UE""" """Clone existing UE"""
ue_id = int(request.form.get("ue_id")) ue_id = int(request.form.get("ue_id"))
@ -1380,12 +1378,12 @@ def edit_enseignants_form_delete(moduleimpl_id, ens_id: int):
# sco_publish( # sco_publish(
# "/do_formsemestre_inscription_create", # "/do_formsemestre_inscription_create",
# sco_formsemestre_inscriptions.do_formsemestre_inscription_create, # sco_formsemestre_inscriptions.do_formsemestre_inscription_create,
# Permission.ScoEtudInscrit, # Permission.EtudInscrit,
# ) # )
# sco_publish( # sco_publish(
# "/do_formsemestre_inscription_edit", # "/do_formsemestre_inscription_edit",
# sco_formsemestre_inscriptions.do_formsemestre_inscription_edit, # sco_formsemestre_inscriptions.do_formsemestre_inscription_edit,
# Permission.ScoEtudInscrit, # Permission.EtudInscrit,
# ) # )
sco_publish( sco_publish(
@ -1409,7 +1407,7 @@ def do_formsemestre_inscription_listinscrits(formsemestre_id, fmt=None):
@bp.route("/formsemestre_desinscription", methods=["GET", "POST"]) @bp.route("/formsemestre_desinscription", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoImplement) @permission_required(Permission.EditFormSemestre)
@scodoc7func @scodoc7func
def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False): def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False):
"""désinscrit l'etudiant de ce semestre (et donc de tous les modules). """désinscrit l'etudiant de ce semestre (et donc de tous les modules).
@ -1493,7 +1491,7 @@ def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False)
sco_publish( sco_publish(
"/do_formsemestre_desinscription", "/do_formsemestre_desinscription",
sco_formsemestre_inscriptions.do_formsemestre_desinscription, sco_formsemestre_inscriptions.do_formsemestre_desinscription,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@ -1503,7 +1501,7 @@ sco_publish(
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
def etud_desinscrit_ue(etudid, formsemestre_id, ue_id): def etud_desinscrit_ue(etudid, formsemestre_id, ue_id):
""" """
- En classique: désinscrit l'etudiant de tous les modules de cette UE dans ce semestre. - En classique: désinscrit l'etudiant de tous les modules de cette UE dans ce semestre.
@ -1551,7 +1549,7 @@ def etud_desinscrit_ue(etudid, formsemestre_id, ue_id):
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
def etud_inscrit_ue(etudid, formsemestre_id, ue_id): def etud_inscrit_ue(etudid, formsemestre_id, ue_id):
""" """
En classic: inscrit l'étudiant à tous les modules de cette UE dans ce semestre. En classic: inscrit l'étudiant à tous les modules de cette UE dans ce semestre.
@ -1592,28 +1590,28 @@ def etud_inscrit_ue(etudid, formsemestre_id, ue_id):
sco_publish( sco_publish(
"/formsemestre_inscription_with_modules_form", "/formsemestre_inscription_with_modules_form",
sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_form, sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_form,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
) )
sco_publish( sco_publish(
"/formsemestre_inscription_with_modules_etud", "/formsemestre_inscription_with_modules_etud",
sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_etud, sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_etud,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
) )
sco_publish( sco_publish(
"/formsemestre_inscription_with_modules", "/formsemestre_inscription_with_modules",
sco_formsemestre_inscriptions.formsemestre_inscription_with_modules, sco_formsemestre_inscriptions.formsemestre_inscription_with_modules,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
) )
sco_publish( sco_publish(
"/formsemestre_inscription_option", "/formsemestre_inscription_option",
sco_formsemestre_inscriptions.formsemestre_inscription_option, sco_formsemestre_inscriptions.formsemestre_inscription_option,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/do_moduleimpl_incription_options", "/do_moduleimpl_incription_options",
sco_formsemestre_inscriptions.do_moduleimpl_incription_options, sco_formsemestre_inscriptions.do_moduleimpl_incription_options,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
) )
sco_publish( sco_publish(
"/formsemestre_inscrits_ailleurs", "/formsemestre_inscrits_ailleurs",
@ -1623,7 +1621,7 @@ sco_publish(
sco_publish( sco_publish(
"/moduleimpl_inscriptions_edit", "/moduleimpl_inscriptions_edit",
sco_moduleimpl_inscriptions.moduleimpl_inscriptions_edit, sco_moduleimpl_inscriptions.moduleimpl_inscriptions_edit,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
@ -1638,7 +1636,7 @@ sco_publish(
@bp.route("/evaluation_delete", methods=["GET", "POST"]) @bp.route("/evaluation_delete", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) @permission_required(Permission.EnsView)
@scodoc7func @scodoc7func
def evaluation_delete(evaluation_id): def evaluation_delete(evaluation_id):
"""Form delete evaluation""" """Form delete evaluation"""
@ -1727,7 +1725,7 @@ def evaluation_delete(evaluation_id):
@bp.route("/evaluation_edit", methods=["GET", "POST"]) @bp.route("/evaluation_edit", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) @permission_required(Permission.EnsView)
@scodoc7func @scodoc7func
def evaluation_edit(evaluation_id): def evaluation_edit(evaluation_id):
"form edit evaluation" "form edit evaluation"
@ -1738,7 +1736,7 @@ def evaluation_edit(evaluation_id):
@bp.route("/evaluation_create", methods=["GET", "POST"]) @bp.route("/evaluation_create", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) @permission_required(Permission.EnsView)
@scodoc7func @scodoc7func
def evaluation_create(moduleimpl_id): def evaluation_create(moduleimpl_id):
"form create evaluation" "form create evaluation"
@ -1816,7 +1814,7 @@ sco_publish(
sco_publish( sco_publish(
"/placement_eval_selectetuds", "/placement_eval_selectetuds",
sco_placement.placement_eval_selectetuds, sco_placement.placement_eval_selectetuds,
Permission.ScoEnsView, Permission.EnsView,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@ -1824,19 +1822,19 @@ sco_publish(
sco_publish( sco_publish(
"/saisie_notes_tableur", "/saisie_notes_tableur",
sco_saisie_notes.saisie_notes_tableur, sco_saisie_notes.saisie_notes_tableur,
Permission.ScoEnsView, Permission.EnsView,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/feuille_saisie_notes", "/feuille_saisie_notes",
sco_saisie_notes.feuille_saisie_notes, sco_saisie_notes.feuille_saisie_notes,
Permission.ScoEnsView, Permission.EnsView,
) )
sco_publish("/saisie_notes", sco_saisie_notes.saisie_notes, Permission.ScoEnsView) sco_publish("/saisie_notes", sco_saisie_notes.saisie_notes, Permission.EnsView)
sco_publish( sco_publish(
"/do_evaluation_set_missing", "/do_evaluation_set_missing",
sco_saisie_notes.do_evaluation_set_missing, sco_saisie_notes.do_evaluation_set_missing,
Permission.ScoEnsView, Permission.EnsView,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
@ -2045,7 +2043,7 @@ sco_publish(
@bp.route("/appreciation_add_form", methods=["GET", "POST"]) @bp.route("/appreciation_add_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEnsView) @permission_required(Permission.EnsView)
@scodoc7func @scodoc7func
def appreciation_add_form( def appreciation_add_form(
etudid=None, etudid=None,
@ -2073,7 +2071,7 @@ def appreciation_add_form(
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
# check custom access permission # check custom access permission
can_edit_app = formsemestre.est_responsable(current_user) or ( can_edit_app = formsemestre.est_responsable(current_user) or (
current_user.has_permission(Permission.ScoEtudInscrit) current_user.has_permission(Permission.EtudInscrit)
) )
if not can_edit_app: if not can_edit_app:
raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation") raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation")
@ -2888,7 +2886,7 @@ def formsemestre_jury_but_erase(formsemestre_id: int, etudid: int = None):
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int): def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
"""Efface toute les décisions d'une année pour cet étudiant""" """Efface toute les décisions d'une année pour cet étudiant"""
etud: Identite = Identite.query.get_or_404(etudid) etud: Identite = Identite.query.get_or_404(etudid)
@ -2932,7 +2930,7 @@ def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
def jury_delete_manual(etudid: int): def jury_delete_manual(etudid: int):
"""Efface toute les décisions d'une année pour cet étudiant""" """Efface toute les décisions d'une année pour cet étudiant"""
etud: Identite = Identite.query.get_or_404(etudid) etud: Identite = Identite.query.get_or_404(etudid)
@ -2978,46 +2976,46 @@ sco_publish(
sco_archives.formsemestre_get_archived_file, sco_archives.formsemestre_get_archived_file,
Permission.ScoView, Permission.ScoView,
) )
sco_publish("/view_apo_csv", sco_etape_apogee_view.view_apo_csv, Permission.ScoEditApo) sco_publish("/view_apo_csv", sco_etape_apogee_view.view_apo_csv, Permission.EditApogee)
sco_publish( sco_publish(
"/view_apo_csv_store", "/view_apo_csv_store",
sco_etape_apogee_view.view_apo_csv_store, sco_etape_apogee_view.view_apo_csv_store,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/view_apo_csv_download_and_store", "/view_apo_csv_download_and_store",
sco_etape_apogee_view.view_apo_csv_download_and_store, sco_etape_apogee_view.view_apo_csv_download_and_store,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/view_apo_csv_delete", "/view_apo_csv_delete",
sco_etape_apogee_view.view_apo_csv_delete, sco_etape_apogee_view.view_apo_csv_delete,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/view_scodoc_etuds", sco_etape_apogee_view.view_scodoc_etuds, Permission.ScoEditApo "/view_scodoc_etuds", sco_etape_apogee_view.view_scodoc_etuds, Permission.EditApogee
) )
sco_publish( sco_publish(
"/view_apo_etuds", sco_etape_apogee_view.view_apo_etuds, Permission.ScoEditApo "/view_apo_etuds", sco_etape_apogee_view.view_apo_etuds, Permission.EditApogee
) )
sco_publish( sco_publish(
"/apo_semset_maq_status", "/apo_semset_maq_status",
sco_etape_apogee_view.apo_semset_maq_status, sco_etape_apogee_view.apo_semset_maq_status,
Permission.ScoEditApo, Permission.EditApogee,
) )
sco_publish( sco_publish(
"/apo_csv_export_results", "/apo_csv_export_results",
sco_etape_apogee_view.apo_csv_export_results, sco_etape_apogee_view.apo_csv_export_results,
Permission.ScoEditApo, Permission.EditApogee,
) )
@bp.route("/formsemestre_set_apo_etapes", methods=["POST"]) @bp.route("/formsemestre_set_apo_etapes", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditApo) @permission_required(Permission.EditApogee)
def formsemestre_set_apo_etapes(): def formsemestre_set_apo_etapes():
"""Change les codes étapes du semestre indiqué. """Change les codes étapes du semestre indiqué.
Args: oid=formsemestre_id, value=chaine "V1RT, V1RT2", codes séparés par des virgules Args: oid=formsemestre_id, value=chaine "V1RT, V1RT2", codes séparés par des virgules
@ -3046,7 +3044,7 @@ def formsemestre_set_apo_etapes():
@bp.route("/formsemestre_set_elt_annee_apo", methods=["POST"]) @bp.route("/formsemestre_set_elt_annee_apo", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditApo) @permission_required(Permission.EditApogee)
def formsemestre_set_elt_annee_apo(): def formsemestre_set_elt_annee_apo():
"""Change les codes étapes du semestre indiqué. """Change les codes étapes du semestre indiqué.
Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
@ -3067,7 +3065,7 @@ def formsemestre_set_elt_annee_apo():
@bp.route("/formsemestre_set_elt_sem_apo", methods=["POST"]) @bp.route("/formsemestre_set_elt_sem_apo", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditApo) @permission_required(Permission.EditApogee)
def formsemestre_set_elt_sem_apo(): def formsemestre_set_elt_sem_apo():
"""Change les codes étapes du semestre indiqué. """Change les codes étapes du semestre indiqué.
Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
@ -3088,7 +3086,7 @@ def formsemestre_set_elt_sem_apo():
@bp.route("/ue_set_apo", methods=["POST"]) @bp.route("/ue_set_apo", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditApo) @permission_required(Permission.EditApogee)
def ue_set_apo(): def ue_set_apo():
"""Change le code APO de l'UE """Change le code APO de l'UE
Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE) Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE)
@ -3109,7 +3107,7 @@ def ue_set_apo():
@bp.route("/module_set_apo", methods=["POST"]) @bp.route("/module_set_apo", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEditApo) @permission_required(Permission.EditApogee)
def module_set_apo(): def module_set_apo():
"""Change le code APO du module """Change le code APO du module
Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE) Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE)
@ -3130,35 +3128,35 @@ def module_set_apo():
# sco_semset # sco_semset
sco_publish("/semset_page", sco_semset.semset_page, Permission.ScoEditApo) sco_publish("/semset_page", sco_semset.semset_page, Permission.EditApogee)
sco_publish( sco_publish(
"/do_semset_create", "/do_semset_create",
sco_semset.do_semset_create, sco_semset.do_semset_create,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/do_semset_delete", "/do_semset_delete",
sco_semset.do_semset_delete, sco_semset.do_semset_delete,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/edit_semset_set_title", "/edit_semset_set_title",
sco_semset.edit_semset_set_title, sco_semset.edit_semset_set_title,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/do_semset_add_sem", "/do_semset_add_sem",
sco_semset.do_semset_add_sem, sco_semset.do_semset_add_sem,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/do_semset_remove_sem", "/do_semset_remove_sem",
sco_semset.do_semset_remove_sem, sco_semset.do_semset_remove_sem,
Permission.ScoEditApo, Permission.EditApogee,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@ -3166,7 +3164,7 @@ sco_publish(
sco_publish( sco_publish(
"/scodoc_table_results", "/scodoc_table_results",
sco_export_results.scodoc_table_results, sco_export_results.scodoc_table_results,
Permission.ScoEditApo, Permission.EditApogee,
) )
sco_publish( sco_publish(
@ -3186,7 +3184,7 @@ sco_publish(
sco_publish( sco_publish(
"/formsemestre_inscr_passage", "/formsemestre_inscr_passage",
sco_inscr_passage.formsemestre_inscr_passage, sco_inscr_passage.formsemestre_inscr_passage,
Permission.ScoEtudInscrit, Permission.EtudInscrit,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
@ -3258,7 +3256,7 @@ sco_publish(
@bp.route("/check_sem_integrity") @bp.route("/check_sem_integrity")
@scodoc @scodoc
@permission_required(Permission.ScoImplement) @permission_required(Permission.EditFormSemestre)
@scodoc7func @scodoc7func
def check_sem_integrity(formsemestre_id, fix=False): def check_sem_integrity(formsemestre_id, fix=False):
"""Debug. """Debug.

View File

@ -48,7 +48,7 @@ from app.views import ScoData
"/formsemestre_change_formation/<int:formsemestre_id>", methods=["GET", "POST"] "/formsemestre_change_formation/<int:formsemestre_id>", methods=["GET", "POST"]
) )
@scodoc @scodoc
@permission_required(Permission.ScoImplement) @permission_required(Permission.EditFormSemestre)
def formsemestre_change_formation(formsemestre_id: int): def formsemestre_change_formation(formsemestre_id: int):
"""Propose de changer un formsemestre de formation. """Propose de changer un formsemestre de formation.
Cette opération est bien sûr impossible... sauf si les deux formations sont identiques. Cette opération est bien sûr impossible... sauf si les deux formations sont identiques.

View File

@ -149,7 +149,7 @@ def table_modules_ue_coefs(formation_id, semestre_idx=None, parcours_id: int = N
@bp.route("/set_module_ue_coef", methods=["POST"]) @bp.route("/set_module_ue_coef", methods=["POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def set_module_ue_coef(): def set_module_ue_coef():
"""Set coef from module to UE""" """Set coef from module to UE"""
try: try:
@ -234,7 +234,7 @@ def edit_modules_ue_coefs():
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
), ),
read_only=locked read_only=locked
or not current_user.has_permission(Permission.ScoChangeFormation), or not current_user.has_permission(Permission.EditFormation),
semestre_idx=semestre_idx, semestre_idx=semestre_idx,
semestre_ids=range(1, formation.get_cursus().NB_SEM + 1), semestre_ids=range(1, formation.get_cursus().NB_SEM + 1),
parcours_id=parcours_id, parcours_id=parcours_id,

View File

@ -63,7 +63,7 @@ def refcomp_show(refcomp_id):
@bp.route("/referentiel/comp/delete/<int:refcomp_id>", methods=["GET", "POST"]) @bp.route("/referentiel/comp/delete/<int:refcomp_id>", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def refcomp_delete(refcomp_id): def refcomp_delete(refcomp_id):
"""Suppression du référentiel de la base. Le fichier source n'est pas affecté.""" """Suppression du référentiel de la base. Le fichier source n'est pas affecté."""
ref = ApcReferentielCompetences.query.get_or_404(refcomp_id) ref = ApcReferentielCompetences.query.get_or_404(refcomp_id)
@ -80,7 +80,7 @@ def refcomp_table():
"""Liste html des ref. comp. chargés dans ce département""" """Liste html des ref. comp. chargés dans ce département"""
refs = ApcReferentielCompetences.query.filter_by(dept_id=g.scodoc_dept_id) refs = ApcReferentielCompetences.query.filter_by(dept_id=g.scodoc_dept_id)
columns_ids = ("type_titre", "specialite_long", "version", "json", "nb_formations") columns_ids = ("type_titre", "specialite_long", "version", "json", "nb_formations")
if current_user.has_permission(Permission.ScoChangeFormation): if current_user.has_permission(Permission.EditFormation):
columns_ids = ("suppr",) + columns_ids columns_ids = ("suppr",) + columns_ids
suppr_icon = scu.icontag( suppr_icon = scu.icontag(
"delete_small_img", border="0", alt="supprimer", title="Supprimer" "delete_small_img", border="0", alt="supprimer", title="Supprimer"
@ -128,7 +128,7 @@ def refcomp_table():
"/referentiel/comp/assoc_formation/<int:formation_id>", methods=["GET", "POST"] "/referentiel/comp/assoc_formation/<int:formation_id>", methods=["GET", "POST"]
) )
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def refcomp_assoc_formation(formation_id: int): def refcomp_assoc_formation(formation_id: int):
"""Formulaire association ref. compétence""" """Formulaire association ref. compétence"""
formation = Formation.query.get_or_404(formation_id) formation = Formation.query.get_or_404(formation_id)
@ -173,7 +173,7 @@ def refcomp_assoc_formation(formation_id: int):
@bp.route("/referentiel/comp/desassoc_formation/<int:formation_id>", methods=["GET"]) @bp.route("/referentiel/comp/desassoc_formation/<int:formation_id>", methods=["GET"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def refcomp_desassoc_formation(formation_id: int): def refcomp_desassoc_formation(formation_id: int):
"""Désassocie la formation de son ref. de compétence""" """Désassocie la formation de son ref. de compétence"""
formation: Formation = Formation.query.get_or_404(formation_id) formation: Formation = Formation.query.get_or_404(formation_id)
@ -188,7 +188,7 @@ def refcomp_desassoc_formation(formation_id: int):
) )
@bp.route("/referentiel/comp/load/<int:formation_id>", methods=["GET", "POST"]) @bp.route("/referentiel/comp/load/<int:formation_id>", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangeFormation) @permission_required(Permission.EditFormation)
def refcomp_load(formation_id=None): def refcomp_load(formation_id=None):
"""Formulaire association ref. compétence""" """Formulaire association ref. compétence"""
if formation_id is not None: if formation_id is not None:

View File

@ -60,12 +60,15 @@ from app.decorators import (
scodoc7func, scodoc7func,
scodoc, scodoc,
) )
from app.forms.generic import SimpleConfirmationForm
from app.forms.main import config_logos, config_main from app.forms.main import config_logos, config_main
from app.forms.main.config_assiduites import ConfigAssiduitesForm from app.forms.main.config_assiduites import ConfigAssiduitesForm
from app.forms.main.config_apo import CodesDecisionsForm from app.forms.main.config_apo import CodesDecisionsForm
from app.forms.main.config_cas import ConfigCASForm from app.forms.main.config_cas import ConfigCASForm
from app.forms.main.config_personalized_links import PersonalizedLinksForm from app.forms.main.config_personalized_links import PersonalizedLinksForm
from app.forms.main.create_dept import CreateDeptForm from app.forms.main.create_dept import CreateDeptForm
from app.forms.main.role_create import CreateRoleForm
from app import models from app import models
from app.models import ( from app.models import (
Departement, Departement,
@ -85,6 +88,7 @@ from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
from app.views import scodoc_bp as bp from app.views import scodoc_bp as bp
import sco_version import sco_version
@ -151,10 +155,88 @@ def config_roles():
permissions_names = sorted(Permission.permission_by_value.values()) permissions_names = sorted(Permission.permission_by_value.values())
roles = Role.query.order_by(Role.name).all() roles = Role.query.order_by(Role.name).all()
return render_template( return render_template(
"role_editor.j2", "scodoc/role_editor.j2",
Permission=Permission, Permission=Permission,
permissions_names=permissions_names, permissions_names=permissions_names,
roles=roles, roles=roles,
SCO_ROLES_DEFAULTS=SCO_ROLES_DEFAULTS,
)
@bp.route("/ScoDoc/permission_info/<string:perm_name>")
@admin_required
def permission_info(perm_name: str):
"""Infos sur une permission"""
permission = Permission.get_by_name(perm_name)
if permission is None:
raise ScoValueError("permission_info: permission inconnue")
return render_template(
"scodoc/permission_info.j2",
permission=permission,
permission_name=perm_name,
Permission=Permission,
)
@bp.route("/ScoDoc/role_info/<string:role_name>")
@admin_required
def role_info(role_name: str):
"""Infos sur un rôle"""
role = Role.query.filter_by(name=role_name).first_or_404()
return render_template(
"scodoc/role_info.j2", role=role, SCO_ROLES_DEFAULTS=SCO_ROLES_DEFAULTS
)
@bp.route("/ScoDoc/role_create", methods=["GET", "POST"])
@admin_required
def role_create():
"""Création d'un nouveau rôle"""
form = CreateRoleForm()
dest_url = url_for("scodoc.config_roles")
if request.method == "POST" and form.cancel.data:
return redirect(dest_url)
if form.validate_on_submit():
role_name = form.name.data.strip()
role: Role = Role.query.filter_by(name=role_name).first()
if role:
raise ScoValueError("Un rôle du même nom existe déjà", dest_url=dest_url)
role = Role(name=role_name)
db.session.add(role)
db.session.commit()
flash(f"Rôle {role_name} créé")
return redirect(dest_url)
roles = Role.query.order_by(Role.name).all()
return render_template(
"scodoc/role_create.j2", form=form, roles_names=[role.name for role in roles]
)
@bp.route("/ScoDoc/role_delete/<string:role_name>", methods=["GET", "POST"])
@admin_required
def role_delete(role_name: str):
"""Suppression d'un rôle"""
role = Role.query.filter_by(name=role_name).first_or_404()
# Ne permet de supprimer les rôles standards (on peut le faire via la ligne de commande ou l'API)
if role.name in SCO_ROLES_DEFAULTS:
raise ScoValueError(
f"Le rôle {role_name} est standard et ne peux pas être supprimé ici."
)
form = SimpleConfirmationForm()
if request.method == "POST" and form.cancel.data:
return redirect(url_for("scodoc.config_roles"))
if form.validate_on_submit():
db.session.delete(role)
db.session.commit()
flash(f"Rôle {role_name} supprimé")
return redirect(url_for("scodoc.config_roles"))
return render_template(
"form_confirmation.j2",
title=f"Supprimer le rôle {role_name} ?",
form=form,
info_message="""<p>Cette suppression est irréversible.</p>""",
) )

View File

@ -130,7 +130,7 @@ def sco_publish(route, function, permission, methods=["GET"]):
@bp.route("/edit_preferences", methods=["GET", "POST"]) @bp.route("/edit_preferences", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoChangePreferences) @permission_required(Permission.EditPreferences)
@scodoc7func @scodoc7func
def edit_preferences(): def edit_preferences():
"""Edit global preferences (lien "Paramétrage" département)""" """Edit global preferences (lien "Paramétrage" département)"""
@ -145,7 +145,7 @@ def formsemestre_edit_preferences(formsemestre_id):
"""Edit preferences for a semestre""" """Edit preferences for a semestre"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem = sco_formsemestre.get_formsemestre(formsemestre_id)
ok = ( ok = (
current_user.has_permission(Permission.ScoImplement) current_user.has_permission(Permission.EditFormSemestre)
or ((current_user.id in sem["responsables"]) and sem["resp_can_edit"]) or ((current_user.id in sem["responsables"]) and sem["resp_can_edit"])
) and (sem["etat"]) ) and (sem["etat"])
if ok: if ok:
@ -196,7 +196,7 @@ class DeptLogosConfigurationForm(FlaskForm):
# @bp.route("/config_logos", methods=["GET", "POST"]) # @bp.route("/config_logos", methods=["GET", "POST"])
# @permission_required(Permission.ScoChangePreferences) # @permission_required(Permission.EditPreferences)
# def config_logos(scodoc_dept): # def config_logos(scodoc_dept):
# "Panneau de configuration général" # "Panneau de configuration général"
# form = DeptLogosConfigurationForm() # form = DeptLogosConfigurationForm()
@ -256,7 +256,7 @@ class DeptLogosConfigurationForm(FlaskForm):
# @bp.route("/config_logos", methods=["GET", "POST"]) # @bp.route("/config_logos", methods=["GET", "POST"])
# @permission_required(Permission.ScoChangePreferences) # @permission_required(Permission.EditPreferences)
# def config_logos(scodoc_dept): # def config_logos(scodoc_dept):
# "Panneau de configuration général" # "Panneau de configuration général"
# form = DeptLogosConfigurationForm() # form = DeptLogosConfigurationForm()
@ -661,25 +661,25 @@ sco_publish(
sco_publish( sco_publish(
"/itemsuivi_suppress", "/itemsuivi_suppress",
sco_debouche.itemsuivi_suppress, sco_debouche.itemsuivi_suppress,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/itemsuivi_create", "/itemsuivi_create",
sco_debouche.itemsuivi_create, sco_debouche.itemsuivi_create,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/itemsuivi_set_date", "/itemsuivi_set_date",
sco_debouche.itemsuivi_set_date, sco_debouche.itemsuivi_set_date,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/itemsuivi_set_situation", "/itemsuivi_set_situation",
sco_debouche.itemsuivi_set_situation, sco_debouche.itemsuivi_set_situation,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
@ -692,14 +692,14 @@ sco_publish(
sco_publish( sco_publish(
"/itemsuivi_tag_set", "/itemsuivi_tag_set",
sco_debouche.itemsuivi_tag_set, sco_debouche.itemsuivi_tag_set,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
@bp.route("/doAddAnnotation", methods=["GET", "POST"]) @bp.route("/doAddAnnotation", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudAddAnnotations) @permission_required(Permission.EtudAddAnnotations)
@scodoc7func @scodoc7func
def doAddAnnotation(etudid, comment): def doAddAnnotation(etudid, comment):
"ajoute annotation sur etudiant" "ajoute annotation sur etudiant"
@ -750,7 +750,7 @@ def doSuppressAnnotation(etudid, annotation_id):
@bp.route("/form_change_coordonnees", methods=["GET", "POST"]) @bp.route("/form_change_coordonnees", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudChangeAdr) @permission_required(Permission.EtudChangeAdr)
@scodoc7func @scodoc7func
def form_change_coordonnees(etudid): def form_change_coordonnees(etudid):
"edit coordonnees etudiant" "edit coordonnees etudiant"
@ -1014,7 +1014,7 @@ def etud_photo_orig_page(etudid=None):
@bp.route("/form_change_photo", methods=["GET", "POST"]) @bp.route("/form_change_photo", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudChangeAdr) @permission_required(Permission.EtudChangeAdr)
@scodoc7func @scodoc7func
def form_change_photo(etudid=None): def form_change_photo(etudid=None):
"""Formulaire changement photo étudiant""" """Formulaire changement photo étudiant"""
@ -1077,7 +1077,7 @@ def form_change_photo(etudid=None):
@bp.route("/form_suppress_photo", methods=["POST", "GET"]) @bp.route("/form_suppress_photo", methods=["POST", "GET"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudChangeAdr) @permission_required(Permission.EtudChangeAdr)
@scodoc7func @scodoc7func
def form_suppress_photo(etudid=None, dialog_confirmed=False): def form_suppress_photo(etudid=None, dialog_confirmed=False):
"""Formulaire suppression photo étudiant""" """Formulaire suppression photo étudiant"""
@ -1102,7 +1102,7 @@ def form_suppress_photo(etudid=None, dialog_confirmed=False):
# #
@bp.route("/form_dem") @bp.route("/form_dem")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def form_dem(etudid, formsemestre_id): def form_dem(etudid, formsemestre_id):
"Formulaire Démission Etudiant" "Formulaire Démission Etudiant"
@ -1116,7 +1116,7 @@ def form_dem(etudid, formsemestre_id):
@bp.route("/form_def") @bp.route("/form_def")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def form_def(etudid, formsemestre_id): def form_def(etudid, formsemestre_id):
"Formulaire Défaillance Etudiant" "Formulaire Défaillance Etudiant"
@ -1174,7 +1174,7 @@ def _form_dem_of_def(
@bp.route("/do_dem_etudiant") @bp.route("/do_dem_etudiant")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def do_dem_etudiant(etudid, formsemestre_id, event_date=None): def do_dem_etudiant(etudid, formsemestre_id, event_date=None):
"Déclare la démission d'un etudiant dans le semestre" "Déclare la démission d'un etudiant dans le semestre"
@ -1190,7 +1190,7 @@ def do_dem_etudiant(etudid, formsemestre_id, event_date=None):
@bp.route("/do_def_etudiant") @bp.route("/do_def_etudiant")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def do_def_etudiant(etudid, formsemestre_id, event_date=None): def do_def_etudiant(etudid, formsemestre_id, event_date=None):
"Déclare la défaillance d'un etudiant dans le semestre" "Déclare la défaillance d'un etudiant dans le semestre"
@ -1230,7 +1230,7 @@ def _do_dem_or_def_etud(
@bp.route("/do_cancel_dem", methods=["GET", "POST"]) @bp.route("/do_cancel_dem", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def do_cancel_dem(etudid, formsemestre_id, dialog_confirmed=False, args=None): def do_cancel_dem(etudid, formsemestre_id, dialog_confirmed=False, args=None):
"Annule une démission" "Annule une démission"
@ -1249,7 +1249,7 @@ def do_cancel_dem(etudid, formsemestre_id, dialog_confirmed=False, args=None):
@bp.route("/do_cancel_def", methods=["GET", "POST"]) @bp.route("/do_cancel_def", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def do_cancel_def(etudid, formsemestre_id, dialog_confirmed=False, args=None): def do_cancel_def(etudid, formsemestre_id, dialog_confirmed=False, args=None):
"Annule la défaillance de l'étudiant" "Annule la défaillance de l'étudiant"
@ -1326,7 +1326,7 @@ def _do_cancel_dem_or_def(
@bp.route("/etudident_create_form", methods=["GET", "POST"]) @bp.route("/etudident_create_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def etudident_create_form(): def etudident_create_form():
"formulaire creation individuelle etudiant" "formulaire creation individuelle etudiant"
@ -1335,7 +1335,7 @@ def etudident_create_form():
@bp.route("/etudident_edit_form", methods=["GET", "POST"]) @bp.route("/etudident_edit_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def etudident_edit_form(): def etudident_edit_form():
"formulaire edition individuelle etudiant" "formulaire edition individuelle etudiant"
@ -1778,7 +1778,7 @@ def _etudident_create_or_edit_form(edit):
@scodoc @scodoc
@permission_required( @permission_required(
Permission.ScoView Permission.ScoView
) # il faut aussi ScoEtudInscrit dans le nouveau dept ) # il faut aussi EtudInscrit dans le nouveau dept
def etud_copy_in_other_dept(etudid: int): def etud_copy_in_other_dept(etudid: int):
"""Crée une copie de l'étudiant (avec ses adresses et codes) dans un autre département """Crée une copie de l'étudiant (avec ses adresses et codes) dans un autre département
et l'inscrit à un formsemestre et l'inscrit à un formsemestre
@ -1797,7 +1797,7 @@ def etud_copy_in_other_dept(etudid: int):
abort(404, description="formsemestre_id invalide") abort(404, description="formsemestre_id invalide")
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
if not current_user.has_permission( if not current_user.has_permission(
Permission.ScoEtudInscrit, formsemestre.departement.acronym Permission.EtudInscrit, formsemestre.departement.acronym
): ):
raise ScoPermissionDenied("non autorisé") raise ScoPermissionDenied("non autorisé")
new_etud = etud.clone(new_dept_id=formsemestre.dept_id) new_etud = etud.clone(new_dept_id=formsemestre.dept_id)
@ -1827,7 +1827,7 @@ def etud_copy_in_other_dept(etudid: int):
departements = { departements = {
dept.id: dept dept.id: dept
for dept in Departement.query.order_by(Departement.acronym) for dept in Departement.query.order_by(Departement.acronym)
if current_user.has_permission(Permission.ScoEtudInscrit, dept.acronym) if current_user.has_permission(Permission.EtudInscrit, dept.acronym)
and dept.id != etud.dept_id and dept.id != etud.dept_id
} }
formsemestres_by_dept = { formsemestres_by_dept = {
@ -1847,7 +1847,7 @@ def etud_copy_in_other_dept(etudid: int):
@bp.route("/etudident_delete", methods=["GET", "POST"]) @bp.route("/etudident_delete", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def etudident_delete(etudid, dialog_confirmed=False): def etudident_delete(etudid, dialog_confirmed=False):
"Delete a student" "Delete a student"
@ -1921,7 +1921,7 @@ def etudident_delete(etudid, dialog_confirmed=False):
@bp.route("/check_group_apogee") @bp.route("/check_group_apogee")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def check_group_apogee(group_id, etat=None, fix=False, fixmail=False): def check_group_apogee(group_id, etat=None, fix=False, fixmail=False):
"""Verification des codes Apogee et mail de tout un groupe. """Verification des codes Apogee et mail de tout un groupe.
@ -2067,7 +2067,7 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False):
@bp.route("/form_students_import_excel", methods=["GET", "POST"]) @bp.route("/form_students_import_excel", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def form_students_import_excel(formsemestre_id=None): def form_students_import_excel(formsemestre_id=None):
"formulaire import xls" "formulaire import xls"
@ -2209,7 +2209,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
@bp.route("/import_generate_excel_sample") @bp.route("/import_generate_excel_sample")
@scodoc @scodoc
@permission_required(Permission.ScoEtudInscrit) @permission_required(Permission.EtudInscrit)
@scodoc7func @scodoc7func
def import_generate_excel_sample(with_codesemestre="1"): def import_generate_excel_sample(with_codesemestre="1"):
"une feuille excel pour importation etudiants" "une feuille excel pour importation etudiants"
@ -2256,7 +2256,7 @@ def form_students_import_infos_admissions(formsemestre_id=None):
"formulaire import xls" "formulaire import xls"
authuser = current_user authuser = current_user
F = html_sco_header.sco_footer() F = html_sco_header.sco_footer()
if not authuser.has_permission(Permission.ScoEtudInscrit): if not authuser.has_permission(Permission.EtudInscrit):
# autorise juste l'export # autorise juste l'export
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(
@ -2356,7 +2356,7 @@ def form_students_import_infos_admissions(formsemestre_id=None):
@bp.route("/formsemestre_import_etud_admission") @bp.route("/formsemestre_import_etud_admission")
@scodoc @scodoc
@permission_required(Permission.ScoEtudChangeAdr) @permission_required(Permission.EtudChangeAdr)
@scodoc7func @scodoc7func
def formsemestre_import_etud_admission(formsemestre_id, import_email=True): def formsemestre_import_etud_admission(formsemestre_id, import_email=True):
"""Reimporte donnees admissions par synchro Portail Apogée""" """Reimporte donnees admissions par synchro Portail Apogée"""
@ -2392,13 +2392,13 @@ def formsemestre_import_etud_admission(formsemestre_id, import_email=True):
sco_publish( sco_publish(
"/photos_import_files_form", "/photos_import_files_form",
sco_trombino.photos_import_files_form, sco_trombino.photos_import_files_form,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/photos_generate_excel_sample", "/photos_generate_excel_sample",
sco_trombino.photos_generate_excel_sample, sco_trombino.photos_generate_excel_sample,
Permission.ScoEtudChangeAdr, Permission.EtudChangeAdr,
) )

View File

@ -133,7 +133,7 @@ class Mode(IntEnum):
@bp.route("/") @bp.route("/")
@bp.route("/index_html") @bp.route("/index_html")
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@scodoc7func @scodoc7func
def index_html( def index_html(
all_depts=False, having_role_name: str = "", with_inactives=False, fmt="html" all_depts=False, having_role_name: str = "", with_inactives=False, fmt="html"
@ -151,7 +151,7 @@ def _get_administrable_depts() -> list[str]:
"""Liste des acronymes des départements dans lesquels l'utilisateur """Liste des acronymes des départements dans lesquels l'utilisateur
courant peut administrer des utilisateurs. courant peut administrer des utilisateurs.
Si SuperAdmin, tous les départements Si SuperAdmin, tous les départements
Sinon, les départements dans lesquels l'utilisateur a la permission ScoUsersAdmin Sinon, les départements dans lesquels l'utilisateur a la permission UsersAdmin
""" """
# #
if current_user.is_administrator(): if current_user.is_administrator():
@ -161,7 +161,7 @@ def _get_administrable_depts() -> list[str]:
) )
else: else:
administrable_dept_acronyms = current_user.get_depts_with_permission( administrable_dept_acronyms = current_user.get_depts_with_permission(
Permission.ScoUsersAdmin Permission.UsersAdmin
) )
if None in administrable_dept_acronyms: if None in administrable_dept_acronyms:
administrable_dept_acronyms = sorted( administrable_dept_acronyms = sorted(
@ -209,7 +209,7 @@ def _get_editable_roles(
@bp.route("/create_user_form", methods=["GET", "POST"]) @bp.route("/create_user_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@scodoc7func @scodoc7func
def create_user_form(user_name=None, edit=0, all_roles=True): def create_user_form(user_name=None, edit=0, all_roles=True):
"form. création ou édition utilisateur" "form. création ou édition utilisateur"
@ -415,7 +415,7 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
"size": 36, "size": 36,
"allow_null": True, "allow_null": True,
"readonly": not cas_enabled "readonly": not cas_enabled
or not current_user.has_permission(Permission.ScoUsersChangeCASId), or not current_user.has_permission(Permission.UsersChangeCASId),
}, },
), ),
( (
@ -596,7 +596,7 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
# empeche modification des paramètres CAS # empeche modification des paramètres CAS
vals.pop("cas_allow_login", None) vals.pop("cas_allow_login", None)
vals.pop("cas_allow_scodoc_login", None) vals.pop("cas_allow_scodoc_login", None)
if not current_user.has_permission(Permission.ScoUsersChangeCASId): if not current_user.has_permission(Permission.UsersChangeCASId):
vals.pop("cas_id", None) vals.pop("cas_id", None)
if "edit" in vals: if "edit" in vals:
edit = int(vals["edit"]) edit = int(vals["edit"])
@ -778,7 +778,7 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
@bp.route("/import_users_generate_excel_sample") @bp.route("/import_users_generate_excel_sample")
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@scodoc7func @scodoc7func
def import_users_generate_excel_sample(): def import_users_generate_excel_sample():
"une feuille excel pour importation utilisateurs" "une feuille excel pour importation utilisateurs"
@ -788,7 +788,7 @@ def import_users_generate_excel_sample():
@bp.route("/import_users_form", methods=["GET", "POST"]) @bp.route("/import_users_form", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
@scodoc7func @scodoc7func
def import_users_form(): def import_users_form():
"""Import utilisateurs depuis feuille Excel""" """Import utilisateurs depuis feuille Excel"""
@ -884,7 +884,7 @@ def import_users_form():
@bp.route("/user_info_page") @bp.route("/user_info_page")
@scodoc @scodoc
@permission_required(Permission.ScoUsersView) @permission_required(Permission.UsersView)
@scodoc7func @scodoc7func
def user_info_page(user_name=None): def user_info_page(user_name=None):
"""Display page of info about given user. """Display page of info about given user.
@ -1070,7 +1070,7 @@ def change_password(user_name, password, password2):
@bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"]) @bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"])
@scodoc @scodoc
@permission_required(Permission.ScoUsersAdmin) @permission_required(Permission.UsersAdmin)
def toggle_active_user(user_name: str = None): def toggle_active_user(user_name: str = None):
"""Change active status of a user account""" """Change active status of a user account"""
if user_name is not None: # scodoc7func converti en int ! if user_name is not None: # scodoc7func converti en int !
@ -1082,7 +1082,7 @@ def toggle_active_user(user_name: str = None):
# permission check: # permission check:
if not ( if not (
current_user.is_administrator() current_user.is_administrator()
or current_user.has_permission(Permission.ScoUsersAdmin, u.dept) or current_user.has_permission(Permission.UsersAdmin, u.dept)
): ):
raise ScoPermissionDenied() raise ScoPermissionDenied()
form = DeactivateUserForm() form = DeactivateUserForm()

View File

@ -19,7 +19,7 @@ depends_on = None
def upgrade(): def upgrade():
# Modification des permissions API # Modification des permissions API
# APIView 1<<40 = 1099511627776 => ScoView = 4 # APIView 1<<40 = 1099511627776 => ScoView = 4
# APIEditGroups 1<<41 = 2199023255552 => ScoEtudChangeGroups = 1<<16 65536 # APIEditGroups 1<<41 = 2199023255552 => EtudChangeGroups = 1<<16 65536
op.execute( op.execute(
""" """
update role set permissions = permissions | 4 where (permissions & 1099511627776) <> 0; update role set permissions = permissions | 4 where (permissions & 1099511627776) <> 0;

View File

@ -289,7 +289,7 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e
In ScoDoc, permissions are not associated to users but to roles. In ScoDoc, permissions are not associated to users but to roles.
Each user has a set of roles in each departement. Each user has a set of roles in each departement.
Example: `flask edit-role -a ScoEditApo Ens` Example: `flask edit-role -a EditApogee Ens`
""" """
if addpermissionname: if addpermissionname:
perm_to_add = Permission.get_by_name(addpermissionname) perm_to_add = Permission.get_by_name(addpermissionname)

View File

@ -95,7 +95,7 @@ class Sample:
HEADERS = get_auth_headers("test", "test") HEADERS = get_auth_headers("test", "test")
elif permission == "ScoSuperAdmin": elif permission == "ScoSuperAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api") HEADERS = get_auth_headers("admin_api", "admin_api")
elif permission == "ScoUsersAdmin": elif permission == "UsersAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api") HEADERS = get_auth_headers("admin_api", "admin_api")
else: else:
raise SampleException(f"Bad permission : {permission}") raise SampleException(f"Bad permission : {permission}")

View File

@ -85,7 +85,7 @@ def test_permissions(api_headers):
"/ScoDoc/api/justificatif/1/justifies", "/ScoDoc/api/justificatif/1/justifies",
] ]
): ):
# On passe la route "api/justificatif/<>/list" car elle nécessite la permission ScoJustifView # On passe la route "api/justificatif/<>/list" car elle nécessite la permission AbsJustifView
# On passe la route "api/justificatif/<>/justifies" car elle nécessite la permission ScoJustifChange # On passe la route "api/justificatif/<>/justifies" car elle nécessite la permission ScoJustifChange
continue continue

View File

@ -125,16 +125,16 @@ def test_roles(api_admin_headers):
assert role["role_name"] == "Test_Y" assert role["role_name"] == "Test_Y"
role = POST_JSON( role = POST_JSON(
"/role/Test_Y/edit", "/role/Test_Y/edit",
{"permissions": ["ScoView", "ScoAbsChange"]}, {"permissions": ["ScoView", "AbsChange"]},
headers=admin_h, headers=admin_h,
) )
assert set(role["permissions"]) == {"ScoView", "ScoAbsChange"} assert set(role["permissions"]) == {"ScoView", "AbsChange"}
role = POST_JSON("/role/Test_Y/add_permission/ScoAbsAddBillet", headers=admin_h) role = POST_JSON("/role/Test_Y/add_permission/AbsAddBillet", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "ScoAbsChange", "ScoAbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"}
role = GET("/role/Test_Y", headers=admin_h) role = GET("/role/Test_Y", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "ScoAbsChange", "ScoAbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"}
role = POST_JSON("/role/Test_Y/remove_permission/ScoAbsChange", headers=admin_h) role = POST_JSON("/role/Test_Y/remove_permission/AbsChange", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "ScoAbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsAddBillet"}
ans = POST_JSON("/role/Test_Y/delete", headers=admin_h) ans = POST_JSON("/role/Test_Y/delete", headers=admin_h)
assert ans["OK"] is True assert ans["OK"] is True
@ -163,7 +163,7 @@ def test_modif_users_depts(api_admin_headers):
) )
role_chef = POST_JSON( role_chef = POST_JSON(
"/role/create/chef", "/role/create/chef",
{"permissions": ["ScoView", "ScoUsersAdmin", "ScoUsersView"]}, {"permissions": ["ScoView", "UsersAdmin", "UsersView"]},
headers=admin_h, headers=admin_h,
) )
_ = POST_JSON( _ = POST_JSON(

View File

@ -91,11 +91,11 @@
"partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST"; "partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST";
"partition";"/partition/1";"ScoView";"GET"; "partition";"/partition/1";"ScoView";"GET";
"permissions";"/permissions";"ScoView";"GET"; "permissions";"/permissions";"ScoView";"GET";
"role-add_permission";"/role/customRole/add_permission/ScoUsersView";"ScoSuperAdmin";"POST"; "role-add_permission";"/role/customRole/add_permission/UsersView";"ScoSuperAdmin";"POST";
"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""ScoUsersView""]}" "role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""UsersView""]}"
"role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST"; "role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST";
"role-edit";"/role/customRole/edit";"ScoSuperAdmin";"POST";"{ ""name"" : ""LaveurDeVitres"", ""permissions"" : [ ""ScoView"" ] }" "role-edit";"/role/customRole/edit";"ScoSuperAdmin";"POST";"{ ""name"" : ""LaveurDeVitres"", ""permissions"" : [ ""ScoView"" ] }"
"role-remove_permission";"/role/customRole/remove_permission/ScoUsersView";"ScoSuperAdmin";"POST"; "role-remove_permission";"/role/customRole/remove_permission/UsersView";"ScoSuperAdmin";"POST";
"role";"/role/Observateur";"ScoView";"GET"; "role";"/role/Observateur";"ScoView";"GET";
"roles";"/roles";"ScoView";"GET"; "roles";"/roles";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET"; "test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET";

Can't render this file because it contains an unexpected character in line 41 and column 2.

View File

@ -32,7 +32,7 @@ def test_password_hashing(test_client):
def test_roles_permissions(test_client): def test_roles_permissions(test_client):
perm = Permission.ScoAbsChange # une permission au hasard perm = Permission.AbsChange # une permission au hasard
role = Role(name="test") role = Role(name="test")
assert not role.has_permission(perm) assert not role.has_permission(perm)
role.add_permission(perm) role.add_permission(perm)
@ -51,19 +51,19 @@ def test_roles_permissions(test_client):
role = Role.query.filter_by(name="Ens").first() role = Role.query.filter_by(name="Ens").first()
assert role assert role
assert role.has_permission(Permission.ScoView) assert role.has_permission(Permission.ScoView)
assert role.has_permission(Permission.ScoAbsChange) assert role.has_permission(Permission.AbsChange)
# Permissions de Admin # Permissions de Admin
role = Role.query.filter_by(name="Admin").first() role = Role.query.filter_by(name="Admin").first()
assert role.has_permission(Permission.ScoEtudChangeAdr) assert role.has_permission(Permission.EtudChangeAdr)
# Permissions de Secr # Permissions de Secr
role = Role.query.filter_by(name="Secr").first() role = Role.query.filter_by(name="Secr").first()
assert role.has_permission(Permission.ScoEtudChangeAdr) assert role.has_permission(Permission.EtudChangeAdr)
assert not role.has_permission(Permission.ScoEditAllNotes) assert not role.has_permission(Permission.EditAllNotes)
def test_users_roles(test_client): def test_users_roles(test_client):
dept = DEPT dept = DEPT
perm = Permission.ScoAbsChange perm = Permission.AbsChange
perm2 = Permission.ScoView perm2 = Permission.ScoView
u = User(user_name="un_enseignant") u = User(user_name="un_enseignant")
db.session.add(u) db.session.add(u)

View File

@ -86,25 +86,25 @@ def create_users(depts: list[Departement]) -> tuple:
"""Crée les roles et utilisateurs nécessaires aux tests""" """Crée les roles et utilisateurs nécessaires aux tests"""
dept = depts[0] dept = depts[0]
# Le rôle standard LecteurAPI existe déjà: lui donne les permissions # Le rôle standard LecteurAPI existe déjà: lui donne les permissions
# ScoView, ScoAbsAddBillet, ScoEtudChangeGroups # ScoView, AbsAddBillet, EtudChangeGroups
role_lecteur = Role.query.filter_by(name="LecteurAPI").first() role_lecteur = Role.query.filter_by(name="LecteurAPI").first()
if role_lecteur is None: if role_lecteur is None:
print("Erreur: rôle LecteurAPI non existant") print("Erreur: rôle LecteurAPI non existant")
sys.exit(1) sys.exit(1)
perm_sco_view = Permission.get_by_name("ScoView") perm_sco_view = Permission.get_by_name("ScoView")
role_lecteur.add_permission(perm_sco_view) role_lecteur.add_permission(perm_sco_view)
perm_sco_users = Permission.get_by_name("ScoUsersView") perm_sco_users = Permission.get_by_name("UsersView")
role_lecteur.add_permission(perm_sco_users) role_lecteur.add_permission(perm_sco_users)
# Edition billets # Edition billets
perm_billets = Permission.get_by_name("ScoAbsAddBillet") perm_billets = Permission.get_by_name("AbsAddBillet")
role_lecteur.add_permission(perm_billets) role_lecteur.add_permission(perm_billets)
perm_groups = Permission.get_by_name("ScoEtudChangeGroups") perm_groups = Permission.get_by_name("EtudChangeGroups")
role_lecteur.add_permission(perm_groups) role_lecteur.add_permission(perm_groups)
db.session.add(role_lecteur) db.session.add(role_lecteur)
# Un role pour juste voir les utilisateurs # Un role pour juste voir les utilisateurs
role_users_viewer = Role( role_users_viewer = Role(
name="UsersViewer", permissions=Permission.ScoUsersView | Permission.ScoView name="UsersViewer", permissions=Permission.UsersView | Permission.ScoView
) )
db.session.add(role_users_viewer) db.session.add(role_users_viewer)
# Role View sur l'API, pour demander un jeton # Role View sur l'API, pour demander un jeton