diff --git a/app/api/assiduites.py b/app/api/assiduites.py index 295fd2ab2f1c005368a4fe08a14afc0e257a0f98..64b0e5096f1bac6c78f3a2fec9004b2ae5b7bd66 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -451,7 +451,7 @@ def count_assiduites_formsemestre( @scodoc @as_json @login_required -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def assiduite_create(etudid: int = None, nip=None, ine=None): """ Création d'une assiduité pour l'étudiant (etudid) @@ -506,7 +506,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None): @scodoc @as_json @login_required -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def assiduites_create(): """ Création d'une assiduité ou plusieurs assiduites @@ -648,7 +648,7 @@ def _create_singular( @login_required @scodoc @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def assiduite_delete(): """ Suppression d'une assiduité à partir de son id @@ -700,7 +700,7 @@ def _delete_singular(assiduite_id: int, database): @login_required @scodoc @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def assiduite_edit(assiduite_id: int): """ Edition d'une assiduité à partir de son id @@ -740,7 +740,7 @@ def assiduite_edit(assiduite_id: int): @login_required @scodoc @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def assiduites_edit(): """ Edition de plusieurs assiduités diff --git a/app/api/billets_absences.py b/app/api/billets_absences.py index 7ada60f6ecaa01e57c2508e9574f0450b95e1d30..98c89dfb00b287192c5b88e39d626f539833345e 100644 --- a/app/api/billets_absences.py +++ b/app/api/billets_absences.py @@ -38,7 +38,7 @@ def billets_absence_etudiant(etudid: int): @api_web_bp.route("/billets_absence/create", methods=["POST"]) @login_required @scodoc -@permission_required(Permission.ScoAbsAddBillet) +@permission_required(Permission.AbsAddBillet) @as_json def billets_absence_create(): """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"]) @login_required @scodoc -@permission_required(Permission.ScoAbsAddBillet) +@permission_required(Permission.AbsAddBillet) @as_json def billets_absence_delete(billet_id: int): """Suppression d'un billet d'absence""" diff --git a/app/api/etudiants.py b/app/api/etudiants.py index 53f2ed3e5fc1c9bcc43e9778f925cd2d868f5a48..41a95760bfd8be605c78ff07c9f787e0ccc88892 100755 --- a/app/api/etudiants.py +++ b/app/api/etudiants.py @@ -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"]) @login_required @scodoc -@permission_required(Permission.ScoEtudChangeAdr) +@permission_required(Permission.EtudChangeAdr) @as_json def set_photo_image(etudid: int = None): """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) if not None in allowed_depts: # restreint aux départements autorisés: diff --git a/app/api/evaluations.py b/app/api/evaluations.py index b1ffee7883fad9c37a8c87e3614322053c14792c..1834f8eb287475dce4039b487cc658135de0c6a5 100644 --- a/app/api/evaluations.py +++ b/app/api/evaluations.py @@ -146,7 +146,7 @@ def evaluation_notes(evaluation_id: int): @api_web_bp.route("/evaluation/<int:evaluation_id>/notes/set", methods=["POST"]) @login_required @scodoc -@permission_required(Permission.ScoEnsView) +@permission_required(Permission.EnsView) @as_json def evaluation_set_notes(evaluation_id: int): """É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"]) @login_required @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 def evaluation_create(moduleimpl_id: int): """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"]) @login_required @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 def evaluation_delete(evaluation_id: int): """Suppression d'une évaluation. diff --git a/app/api/formations.py b/app/api/formations.py index e8a145a5a0c895c203ca3ed490f181038a9a89a5..8a5afe5bf35d2abf099ed09c02774403e626a700 100644 --- a/app/api/formations.py +++ b/app/api/formations.py @@ -251,7 +251,7 @@ def referentiel_competences(formation_id: int): @api_web_bp.route("/set_ue_parcours/<int:ue_id>", methods=["POST"]) @login_required @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) @as_json def set_ue_parcours(ue_id: int): """Associe UE et parcours BUT. @@ -286,7 +286,7 @@ def set_ue_parcours(ue_id: int): ) @login_required @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) @as_json def assoc_ue_niveau(ue_id: int, niveau_id: int): """Associe l'UE au niveau de compétence""" @@ -315,7 +315,7 @@ def assoc_ue_niveau(ue_id: int, niveau_id: int): ) @login_required @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) @as_json def desassoc_ue_niveau(ue_id: int): """Désassocie cette UE de son niveau de compétence diff --git a/app/api/jury.py b/app/api/jury.py index 9d4aad56bbd592811d30159c8b3fabc58cb42768..a48b6357a033676fd3961f6c70a80fd05ab0d579 100644 --- a/app/api/jury.py +++ b/app/api/jury.py @@ -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 # rattachées à un formsemestre) 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)") else: if validation.formsemestre: @@ -128,7 +128,7 @@ def _validation_ue_delete(etudid: int, validation_id: int): validation.formsemestre.dept_id != g.scodoc_dept_id ) or not validation.formsemestre.can_edit_jury(): 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 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 @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @as_json def autorisation_inscription_delete(etudid: int, validation_id: int): "Efface cette validation" @@ -178,7 +178,7 @@ def autorisation_inscription_delete(etudid: int, validation_id: int): ) @login_required @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @as_json def validation_rcue_record(etudid: int): """Enregistre une validation de RCUE. @@ -305,7 +305,7 @@ def validation_rcue_record(etudid: int): ) @login_required @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @as_json def validation_rcue_delete(etudid: int, validation_id: int): "Efface cette validation" @@ -333,7 +333,7 @@ def validation_rcue_delete(etudid: int, validation_id: int): ) @login_required @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @as_json def validation_annee_but_delete(etudid: int, validation_id: int): "Efface cette validation" diff --git a/app/api/justificatifs.py b/app/api/justificatifs.py index a85685f7e57211acaff27f15d619040ad392f928..bac373bff7b37854b8e53959097197784cca03d9 100644 --- a/app/api/justificatifs.py +++ b/app/api/justificatifs.py @@ -241,7 +241,7 @@ def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False): @scodoc @login_required @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_create(etudid: int = None, nip=None, ine=None): """ Création d'un justificatif pour l'étudiant (etudid) @@ -372,7 +372,7 @@ def _create_singular( @login_required @scodoc @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_edit(justif_id: int): """ Edition d'un justificatif à partir de son id @@ -471,7 +471,7 @@ def justif_edit(justif_id: int): @login_required @scodoc @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_delete(): """ Suppression d'un justificatif à partir de son id @@ -534,7 +534,7 @@ def _delete_singular(justif_id: int, database): @scodoc @login_required @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_import(justif_id: int = None): """ 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"]) @scodoc @login_required -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_export(justif_id: int = None, filename: str = None): """ Retourne un fichier d'une archive d'un justificatif @@ -610,7 +610,7 @@ def justif_export(justif_id: int = None, filename: str = None): @scodoc @login_required @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_remove(justif_id: int = None): """ Supression d'un fichier ou d'une archive @@ -700,7 +700,7 @@ def justif_list(justif_id: int = None): for filename in filenames: if int(filename[1]) == current_user.id or current_user.has_permission( - Permission.ScoJustifView + Permission.AbsJustifView ): retour["filenames"].append(filename[0]) return retour @@ -712,7 +712,7 @@ def justif_list(justif_id: int = None): @scodoc @login_required @as_json -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def justif_justifies(justif_id: int = None): """ Liste assiduite_id justifiées par le justificatif diff --git a/app/api/semset.py b/app/api/semset.py index 5eba3f3ee23ea08da536cdca0b592e74ff44f0b6..9869e6f8d8cd89ef0e5b50be1677b204db1514e9 100644 --- a/app/api/semset.py +++ b/app/api/semset.py @@ -23,7 +23,7 @@ # @api_web_bp.route("/semset/set_periode/<int:semset_id>", methods=["POST"]) # @login_required # @scodoc -# @permission_required(Permission.ScoEditApo) +# @permission_required(Permission.EditApogee) # # TODO à modifier pour utiliser @as_json # def semset_set_periode(semset_id: int): # "Change la période d'un semset" diff --git a/app/api/users.py b/app/api/users.py index cf017ee6df7f7c6593960b42db2478ea9916a698..4fe895107aeefa4cbc8d823f740b49af1f91c546 100644 --- a/app/api/users.py +++ b/app/api/users.py @@ -13,7 +13,7 @@ from flask import g, request from flask_json import as_json 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.scodoc.sco_utils import json_error 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>") @login_required @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @as_json def user_info(uid: int): """ @@ -39,7 +39,7 @@ def user_info(uid: int): if user is None: return json_error(404, "user not found") 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): 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)) .filter(UserRole.user == current_user) .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) @@ -89,7 +89,7 @@ def users_info_query(): @api_web_bp.route("/user/create", methods=["POST"]) @login_required @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @as_json def user_create(): """Création d'un utilisateur @@ -112,7 +112,7 @@ def user_create(): dept = data.get("dept") if dept == "@all": 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): return json_error(403, "user_create: departement non autorise") if (dept is not None) and ( @@ -132,7 +132,7 @@ def user_create(): @api_web_bp.route("/user/<int:uid>/edit", methods=["POST"]) @login_required @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @as_json def user_edit(uid: int): """Modification d'un utilisateur @@ -152,7 +152,7 @@ def user_edit(uid: int): if dest_dept is not False: if dest_dept == "@all": 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 ( (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"]) @login_required @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @as_json def user_password(uid: int): """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") if not is_valid_password(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)): return json_error(403, "user_password: departement non autorise") 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") @login_required @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @as_json def list_permissions(): """Liste des noms de permissions définies""" @@ -282,7 +282,7 @@ def list_permissions(): @api_web_bp.route("/role/<string:role_name>") @login_required @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @as_json def list_role(role_name: str): """Un rôle""" @@ -293,7 +293,7 @@ def list_role(role_name: str): @api_web_bp.route("/roles") @login_required @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @as_json def list_roles(): """Tous les rôles définis""" @@ -321,6 +321,7 @@ def role_permission_add(role_name: str, perm_name: str): role.add_permission(permission) db.session.add(role) db.session.commit() + log(f"role_permission_add({role_name}, {perm_name})") return role.to_dict() @@ -345,6 +346,7 @@ def role_permission_remove(role_name: str, perm_name: str): role.remove_permission(permission) db.session.add(role) db.session.commit() + log(f"role_permission_remove({role_name}, {perm_name})") return role.to_dict() diff --git a/app/auth/models.py b/app/auth/models.py index 3115119135f9d88a94ec991a8f1f0cb4d6f60bce..d0e85e9108df898a752fa094daaa388051a9a797 100644 --- a/app/auth/models.py +++ b/app/auth/models.py @@ -541,6 +541,10 @@ class Role(db.Model): "Remove all permissions from role" 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]): """Set permissions, given as a list of permissions names. Raises ScoValueError if invalid permission.""" diff --git a/app/auth/routes.py b/app/auth/routes.py index 235b9e5b898cf94ac9f210f71288ba9d4e0edad7..7818e60b1d1b06e7e193b6a43472aeadd4381b41 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -21,7 +21,9 @@ from app.auth.forms import ( from app.auth.models import Role, User, invalid_user_name from app.auth.email import send_password_reset_email from app.decorators import admin_required +from app.forms.generic import SimpleConfirmationForm from app.models.config import ScoDocSiteConfig +from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS from app.scodoc import sco_utils as scu _ = lambda x: x # sans babel @@ -158,9 +160,25 @@ def reset_password(token): @admin_required def reset_standard_roles_permissions(): "Réinitialise (recrée au besoin) les rôles standards de ScoDoc et leurs permissions" - Role.reset_standard_roles_permissions() - flash("rôles standards réinitialisés !") - return redirect(url_for("scodoc.configuration")) + form = SimpleConfirmationForm() + if request.method == "POST" and form.cancel.data: + 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") diff --git a/app/entreprises/app_relations_entreprises.py b/app/entreprises/app_relations_entreprises.py index e8cce1e1f820072282efa357559b1d80c53de50f..b8bd683ddad407f1ea2e00306a07479fbc207b7f 100644 --- a/app/entreprises/app_relations_entreprises.py +++ b/app/entreprises/app_relations_entreprises.py @@ -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 """ - if current_user.has_permission(Permission.RelationsEntreprisesChange, None): + if current_user.has_permission(Permission.RelationsEntrepEdit, None): return True for offre_dept in offre_depts: if offre_dept.dept_id in depts: diff --git a/app/entreprises/routes.py b/app/entreprises/routes.py index f9eac4f9addffe08f4394fb1366bf0db2ab558e2..60d567abf75e6396d89bb90d6d81ae875b9eaab9 100644 --- a/app/entreprises/routes.py +++ b/app/entreprises/routes.py @@ -62,7 +62,7 @@ from config import Config @bp.route("/", methods=["GET", "POST"]) -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def index(): """ 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"]) -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def logs(): """ Permet d'afficher les logs (toutes les entreprises) @@ -115,7 +115,7 @@ def logs(): @bp.route("/correspondants", methods=["GET"]) -@permission_required(Permission.RelationsEntreprisesCorrespondants) +@permission_required(Permission.RelationsEntrepViewCorrs) def correspondants(): """ 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"]) -@permission_required(Permission.RelationsEntreprisesValidate) +@permission_required(Permission.RelationsEntrepValidate) def validation(): """ 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"]) -@permission_required(Permission.RelationsEntreprisesValidate) +@permission_required(Permission.RelationsEntrepValidate) def fiche_entreprise_validation(entreprise_id): """ 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesValidate) +@permission_required(Permission.RelationsEntrepValidate) def validate_entreprise(entreprise_id): """ Permet de valider une entreprise @@ -214,7 +214,7 @@ def validate_entreprise(entreprise_id): "/fiche_entreprise_validation/<int:entreprise_id>/delete_validation_entreprise", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesValidate) +@permission_required(Permission.RelationsEntrepValidate) def delete_validation_entreprise(entreprise_id): """ 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.") return redirect(url_for("entreprises.validation")) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supression entreprise", form=form, 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"]) -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def offres_recues(): """ Permet d'afficher la page où l'on peut voir les offres reçues @@ -290,7 +290,7 @@ def offres_recues(): @bp.route( "/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): """ Permet de supprimer une offre reçue @@ -304,7 +304,7 @@ def delete_offre_recue(envoi_offre_id): @bp.route("/preferences", methods=["GET", "POST"]) -@permission_required(Permission.RelationsEntreprisesValidate) +@permission_required(Permission.RelationsEntrepValidate) def preferences(): """ 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"]) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_entreprise(): """ Permet d'ajouter une entreprise dans la base avec un formulaire @@ -385,7 +385,7 @@ def add_entreprise(): notes=form.notes.data.strip(), ) db.session.add(correspondant) - if current_user.has_permission(Permission.RelationsEntreprisesValidate, None): + if current_user.has_permission(Permission.RelationsEntrepValidate, None): entreprise.visible = True lien_entreprise = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>{entreprise.nom}</a>" log = EntrepriseHistorique( @@ -414,7 +414,7 @@ def add_entreprise(): @bp.route("/fiche_entreprise/<int:entreprise_id>", methods=["GET"]) -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def fiche_entreprise(entreprise_id): """ 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"]) -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def logs_entreprise(entreprise_id): """ 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") -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def offres_expirees(entreprise_id): """ Permet d'afficher la liste des offres expirés d'une entreprise @@ -499,7 +499,7 @@ def offres_expirees(entreprise_id): @bp.route( "/fiche_entreprise/<int:entreprise_id>/edit_entreprise", methods=["GET", "POST"] ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def edit_entreprise(entreprise_id): """ 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"]) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def fiche_entreprise_desactiver(entreprise_id): """ 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) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Désactiver entreprise", form=form, 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"]) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def fiche_entreprise_activer(entreprise_id): """ Permet d'activer une entreprise @@ -645,7 +645,7 @@ def fiche_entreprise_activer(entreprise_id): url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Activer entreprise", form=form, 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) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supprimer taxe apprentissage", form=form, 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"]) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_offre(entreprise_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def edit_offre(entreprise_id, offre_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def delete_offre(entreprise_id, offre_id): """ 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) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supression offre", form=form, 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def expired(entreprise_id, offre_id): """ 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_site(entreprise_id): """ 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_correspondant(entreprise_id, site_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def edit_correspondant(entreprise_id, site_id, correspondant_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def delete_correspondant(entreprise_id, site_id, correspondant_id): """ Permet de supprimer un correspondant @@ -1289,7 +1289,7 @@ def delete_correspondant(entreprise_id, site_id, correspondant_id): ) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supression correspondant", form=form, 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") -@permission_required(Permission.RelationsEntreprisesView) +@permission_required(Permission.RelationsEntrepView) def contacts(entreprise_id): """ 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_contact(entreprise_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def edit_contact(entreprise_id, contact_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def delete_contact(entreprise_id, contact_id): """ Permet de supprimer un contact @@ -1458,7 +1458,7 @@ def delete_contact(entreprise_id, contact_id): url_for("entreprises.contacts", entreprise_id=contact.entreprise) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supression contact", form=form, 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_stage_apprentissage(entreprise_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) 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 @@ -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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) 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 @@ -1629,7 +1629,7 @@ def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id): ) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Supression stage/apprentissage", form=form, 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesSend) +@permission_required(Permission.RelationsEntrepSend) def envoyer_offre(entreprise_id, offre_id): """ Permet d'envoyer une offre à un utilisateur ScoDoc @@ -1686,7 +1686,7 @@ def envoyer_offre(entreprise_id, offre_id): @bp.route("/etudiants") -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) @as_json def json_etudiants(): """ @@ -1717,7 +1717,7 @@ def json_etudiants(): @bp.route("/responsables") -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def json_responsables(): """ Permet de récuperer un JSON avec tous les utilisateurs ScoDoc @@ -1743,7 +1743,7 @@ def json_responsables(): @bp.route("/export_donnees") -@permission_required(Permission.RelationsEntreprisesExport) +@permission_required(Permission.RelationsEntrepExport) def export_donnees(): """ 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") -@permission_required(Permission.RelationsEntreprisesExport) +@permission_required(Permission.RelationsEntrepExport) def import_donnees_get_file_sample(): """ 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"]) -@permission_required(Permission.RelationsEntreprisesExport) +@permission_required(Permission.RelationsEntrepExport) def import_donnees(): """ Permet d'importer des entreprises à partir d'un fichier excel (.xlsx) @@ -1850,7 +1850,7 @@ def import_donnees(): @bp.route( "/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): """ 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", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def add_offre_file(entreprise_id, offre_id): """ 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>", methods=["GET", "POST"], ) -@permission_required(Permission.RelationsEntreprisesChange) +@permission_required(Permission.RelationsEntrepEdit) def delete_offre_file(entreprise_id, offre_id, filedir): """ Permet de supprimer un fichier d'une offre @@ -1959,7 +1959,7 @@ def delete_offre_file(entreprise_id, offre_id, filedir): ) ) return render_template( - "entreprises/form_confirmation.j2", + "form_confirmation.j2", title="Suppression fichier d'une offre", form=form, info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression", diff --git a/app/forms/generic.py b/app/forms/generic.py new file mode 100644 index 0000000000000000000000000000000000000000..ec301f8d474fba1cf312507592c2f941c5fee3fb --- /dev/null +++ b/app/forms/generic.py @@ -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) diff --git a/app/forms/main/role_create.py b/app/forms/main/role_create.py new file mode 100644 index 0000000000000000000000000000000000000000..c3a2b150e42bc233f559df8fd679274dc9f6e088 --- /dev/null +++ b/app/forms/main/role_create.py @@ -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}) diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index a5b20b1248ee97d38347b72af354936456a992d3..f4a4ea9c156fbe05f55db6d07d6cf8e1285901cf 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -424,7 +424,7 @@ class FormSemestre(db.Model): def can_be_edited_by(self, user): """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 [ resp.id for resp in self.responsables ]: @@ -607,7 +607,7 @@ class FormSemestre(db.Model): def est_chef_or_diretud(self, user: User = None): "Vrai si utilisateur (par def. current) est admin, chef dept ou responsable du semestre" 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 ) @@ -618,7 +618,7 @@ class FormSemestre(db.Model): if not self.etat: return False # semestre verrouillé user = user or current_user - if user.has_permission(Permission.ScoEtudChangeGroups): + if user.has_permission(Permission.EtudChangeGroups): return True # typiquement admin, chef dept return self.est_responsable(user) @@ -632,9 +632,9 @@ class FormSemestre(db.Model): def can_edit_pv(self, user: User = None): "Vrai si utilisateur (par def. current) peut editer un PV de jury de ce semestre" 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( - Permission.ScoEtudChangeAdr + Permission.EtudChangeAdr ) def annee_scolaire(self) -> int: diff --git a/app/models/moduleimpls.py b/app/models/moduleimpls.py index 27df7f48ef7219c5a6b91bdf9251af4d3bb8e525..3ccff4cf8cfd43322772f39b9c5b0cd032a81ede 100644 --- a/app/models/moduleimpls.py +++ b/app/models/moduleimpls.py @@ -107,7 +107,7 @@ class ModuleImpl(db.Model): """ # acces pour resp. moduleimpl et resp. form semestre (dir etud) if ( - user.has_permission(Permission.ScoEditAllEvals) + user.has_permission(Permission.EditAllEvals) or user.id == self.responsable_id 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: return False # semestre verrouillé 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): # il y a des décisions de jury dans ce semestre ! return can_edit_all_notes or is_dir_etud @@ -155,7 +155,7 @@ class ModuleImpl(db.Model): return False # -- check access # admin ou resp. semestre avec flag resp_can_change_resp - if user.has_permission(Permission.ScoImplement): + if user.has_permission(Permission.EditFormSemestre): return True if ( user.id in [resp.id for resp in self.formsemestre.responsables] diff --git a/app/scodoc/html_sidebar.py b/app/scodoc/html_sidebar.py index 1f8ede5d51ac576fd170b038f2d1057ac904ba41..0613ec02821c190de9cd0f0ba4df85a1cd34de59 100755 --- a/app/scodoc/html_sidebar.py +++ b/app/scodoc/html_sidebar.py @@ -56,18 +56,18 @@ def sidebar_common(): <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( f""" <a href="{scu.AssiduitesURL()}" class="sidebar">Assiduité</a> <br> """ ) if current_user.has_permission( - Permission.ScoUsersAdmin - ) or current_user.has_permission(Permission.ScoUsersView): + Permission.UsersAdmin + ) or current_user.has_permission(Permission.UsersView): H.append( 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( f"""<a href="{url_for("scolar.edit_preferences", scodoc_dept=g.scodoc_dept)}" class="sidebar">Paramétrage</a> <br>""" @@ -126,7 +126,7 @@ def sidebar(etudid: int = None): <br>{ nbabsjust } J., { nbabsnj } N.J.</span>""" ) H.append("<ul>") - if current_user.has_permission(Permission.ScoAbsChange): + if current_user.has_permission(Permission.AbsChange): H.append( f""" <li><a href="{ url_for('assiduites.signal_assiduites_etud', scodoc_dept=g.scodoc_dept, etudid=etudid) }">Ajouter</a></li> diff --git a/app/scodoc/sco_archives_etud.py b/app/scodoc/sco_archives_etud.py index 4bc76a10f8a2c6b0febd3c81fd59f30c0811fd70..e3275a8cc49e563a35e1f15a2b4efaa8555ef0fe 100644 --- a/app/scodoc/sco_archives_etud.py +++ b/app/scodoc/sco_archives_etud.py @@ -58,7 +58,7 @@ ETUDS_ARCHIVER = EtudsArchiver() def can_edit_etud_archive(authuser): """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): diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index b1600c1d5a27bb20b2490ad8d5076bb7da8459ed..e0b64eb5c05000d7cfc6f8ad31f4f6bfcd0ddcb0 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -954,7 +954,7 @@ def can_send_bulletin_by_mail(formsemestre_id): sem = sco_formsemestre.get_formsemestre(formsemestre_id) return ( 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"] ) @@ -1213,7 +1213,7 @@ def make_menu_autres_operations( }, "enabled": ( 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, "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", diff --git a/app/scodoc/sco_bulletins_legacy.py b/app/scodoc/sco_bulletins_legacy.py index 9650e74ac9d1b467b66a9c2212369050f080a304..04a630ca0bb9779c9837b476acda5354dacd7e5d 100644 --- a/app/scodoc/sco_bulletins_legacy.py +++ b/app/scodoc/sco_bulletins_legacy.py @@ -327,9 +327,9 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator): H.append("""<p class="bull_situation">%(situation)s</p>""" % I) # --- 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 ( - authuser.has_permission(Permission.ScoEtudInscrit) + authuser.has_permission(Permission.EtudInscrit) ) H.append('<div class="bull_appreciations">') appreciations = BulAppreciations.get_appreciations_list( diff --git a/app/scodoc/sco_bulletins_standard.py b/app/scodoc/sco_bulletins_standard.py index ab49f8a8b1e77f017c5c8d37a82c2952f7ce52ad..715f17a910e7540ac54818c3b265ebb590df4269 100644 --- a/app/scodoc/sco_bulletins_standard.py +++ b/app/scodoc/sco_bulletins_standard.py @@ -155,9 +155,9 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator): # ---- 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 ( - self.authuser.has_permission(Permission.ScoEtudInscrit) + self.authuser.has_permission(Permission.EtudInscrit) ) H.append('<div class="bull_appreciations">') appreciations = BulAppreciations.get_appreciations_list( diff --git a/app/scodoc/sco_dept.py b/app/scodoc/sco_dept.py index 010cb53936a7308ff4518ed3821f45bd308a603b..8e7fc1ef0af1ebc0b0970c943b74402804045404 100644 --- a/app/scodoc/sco_dept.py +++ b/app/scodoc/sco_dept.py @@ -148,7 +148,7 @@ def index_html(showcodes=0, showsemtable=0): </p>""" ) # - if current_user.has_permission(Permission.ScoEtudInscrit): + if current_user.has_permission(Permission.EtudInscrit): H.append( """<hr> <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( f"""<hr> <h3>Exports Apogée</h3> @@ -247,7 +247,7 @@ def _sem_table_gt(sems, showcodes=False): columns_ids = ("formsemestre_id",) + columns_ids 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" tab = GenTable( titles={ diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index 31148e0aad2d12f3a6f57b26168b2202597a1239..ea0ca9fb7b3f05704a29a8eeda7a1dd546ace015 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -908,7 +908,7 @@ def module_table(formation_id): <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}): H.append('<li class="notes_module_list">%s' % module_dict) diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index 80047fcd66774f396553c72d1bf60fc9fb495d93..bcc343277e4fb6ac64df8b8cb0540fda2f57b5b1 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -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] - 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 # On autorise maintenant la modification des formations qui ont # 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 editable = has_perm_change tag_editable = ( - current_user.has_permission(Permission.ScoEditFormationTags) or has_perm_change + current_user.has_permission(Permission.EditFormationTags) or has_perm_change ) if locked: lockicon = scu.icontag("lock32_img", title="verrouillé") @@ -835,7 +835,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours); </a> """ msg_refcomp = "changer" H.append(f"""<ul><li>{descr_refcomp}""") - if current_user.has_permission(Permission.ScoChangeFormation): + if current_user.has_permission(Permission.EditFormation): if ( formation.referentiel_competence is None 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("</ul>") - if current_user.has_permission(Permission.ScoImplement): + if current_user.has_permission(Permission.EditFormSemestre): H.append( f"""<ul> <li><a class="stdlink" href="{ diff --git a/app/scodoc/sco_formation_recap.py b/app/scodoc/sco_formation_recap.py index 02c2578d36dc9dca302f457e92a7392ca64693d1..322ac0c31abd76b93971ac420b10bcb851e84dc7 100644 --- a/app/scodoc/sco_formation_recap.py +++ b/app/scodoc/sco_formation_recap.py @@ -50,7 +50,7 @@ def formation_table_recap(formation_id, fmt="html") -> Response: T = [] formation = Formation.query.get_or_404(formation_id) 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 for ue in ues: # L'UE @@ -138,7 +138,7 @@ def formation_table_recap(formation_id, fmt="html") -> Response: title = f"""Formation {formation.titre} ({formation.acronyme}) [version {formation.version}] code {formation.formation_code}""" 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" tab = GenTable( diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py index c58a81d23c3e0472459e264ea6bb25ad8539d8ed..dbd864f5313c58388e92c3d0991f06cc5a5ba297 100644 --- a/app/scodoc/sco_formations.py +++ b/app/scodoc/sco_formations.py @@ -498,7 +498,7 @@ def formation_list_table() -> GenTable: "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: rows = [] diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index bd0f6f42aa37c790cbd49ff3e6339ef98ec0c092..1aedb43e7430878a7ad0e1448109d071d18aa22c 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -144,7 +144,7 @@ def formsemestre_editwithmodules(formsemestre_id): def can_edit_sem(formsemestre_id: int = None, sem=None): """Return sem if user can edit it, False otherwise""" 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"]: return False return sem @@ -162,9 +162,9 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N "Form choix modules / responsables et création formsemestre" vals = scu.get_request_args() # 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: - # 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") else: 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 += [ ( "resp_can_edit", @@ -1539,7 +1539,7 @@ def do_formsemestre_delete(formsemestre_id): # --------------------------------------------------------------------------------------- def formsemestre_edit_options(formsemestre_id): """dialog to change formsemestre options - (accessible par ScoImplement ou dir. etudes) + (accessible par EditFormSemestre ou dir. etudes) """ log("formsemestre_edit_options") ok, err = sco_permissions_check.check_access_diretud(formsemestre_id) diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index 520af7e8f4e06eca4629e793ddd470ef0504783c..f15c5ed6ace4e8cbd141bd0c119eb5edefc50eba 100755 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -157,7 +157,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: # L'utilisateur est-il resp. du semestre ? 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., ...): - 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 ) # Peut modifier le semestre (si n'est pas verrouillé): @@ -236,7 +236,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "title": "Cloner ce semestre", "endpoint": "notes.formsemestre_clone", "args": {"formsemestre_id": formsemestre_id}, - "enabled": current_user.has_permission(Permission.ScoImplement), + "enabled": current_user.has_permission(Permission.EditFormSemestre), "helpmsg": "", }, { @@ -246,7 +246,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "formsemestre_id": formsemestre_id, "formation_id": formsemestre.formation_id, }, - "enabled": current_user.has_permission(Permission.ScoChangeFormation) + "enabled": current_user.has_permission(Permission.EditFormation) and formsemestre.etat, "helpmsg": "", }, @@ -254,7 +254,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "title": "Supprimer ce semestre", "endpoint": "notes.formsemestre_delete", "args": {"formsemestre_id": formsemestre_id}, - "enabled": current_user.has_permission(Permission.ScoImplement), + "enabled": current_user.has_permission(Permission.EditFormSemestre), "helpmsg": "", }, ] @@ -283,7 +283,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "title": "Passage des étudiants depuis d'autres semestres", "endpoint": "notes.formsemestre_inscr_passage", "args": {"formsemestre_id": formsemestre_id}, - "enabled": current_user.has_permission(Permission.ScoEtudInscrit) + "enabled": current_user.has_permission(Permission.EtudInscrit) and formsemestre.etat, }, { @@ -298,14 +298,14 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "title": "Inscrire un étudiant", "endpoint": "notes.formsemestre_inscription_with_modules_etud", "args": {"formsemestre_id": formsemestre_id}, - "enabled": current_user.has_permission(Permission.ScoEtudInscrit) + "enabled": current_user.has_permission(Permission.EtudInscrit) and formsemestre.etat, }, { "title": "Importer des étudiants dans ce semestre (table Excel)", "endpoint": "scolar.form_students_import_excel", "args": {"formsemestre_id": formsemestre_id}, - "enabled": current_user.has_permission(Permission.ScoEtudInscrit) + "enabled": current_user.has_permission(Permission.EtudInscrit) and formsemestre.etat, }, { @@ -318,7 +318,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str: "title": "Resynchroniser données identité", "endpoint": "scolar.formsemestre_import_etud_admission", "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"), }, { @@ -812,7 +812,7 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str: """La section avec les groupes et l'assiduité""" H = [] # 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( 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_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] ) use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id) diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 8743a04696b5c233db157303a39d077d491d7478..76ce5c29a0efe44852e144acb4b1e25261a71c42 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -1291,7 +1291,7 @@ def _get_etud_ue_cap_html(etud: Identite, formsemestre: FormSemestre) -> str: origine += f" (<b>S{validation.semestre_id}</b>)" H.append(f"""<li>{validation.html()}""") 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( f""" diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py index 179160baa2f16c59126fa60fbcb6dac16c470242..0e46b1b451ce1d519920c07ab6cab57c811c3bef 100644 --- a/app/scodoc/sco_groups_view.py +++ b/app/scodoc/sco_groups_view.py @@ -865,13 +865,13 @@ def tab_absences_html(groups_infos, etat=None): # Lien pour verif codes INE/NIP # (pour tous les etudiants du semestre) 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( '<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 "") ) # Lien pour ajout fichiers étudiants - if authuser.has_permission(Permission.ScoEtudAddAnnotations): + if authuser.has_permission(Permission.EtudAddAnnotations): 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>""" % (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): """Formulaire choix jour semaine pour saisie.""" authuser = current_user - if not authuser.has_permission(Permission.ScoAbsChange): + if not authuser.has_permission(Permission.AbsChange): return "" return f""" <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 def form_choix_saisie_semaine(groups_infos): authuser = current_user - if not authuser.has_permission(Permission.ScoAbsChange): + if not authuser.has_permission(Permission.AbsChange): return "" query_args = parse_qs(request.query_string) moduleimpl_id = query_args.get("moduleimpl_id", [None])[0] diff --git a/app/scodoc/sco_moduleimpl.py b/app/scodoc/sco_moduleimpl.py index 415c442d9528aab7a0857ef89554ddfa69370ecd..d677a7b0e315691b4487151de61e45436f261dd4 100644 --- a/app/scodoc/sco_moduleimpl.py +++ b/app/scodoc/sco_moduleimpl.py @@ -375,7 +375,7 @@ def can_change_module_resp(moduleimpl_id): raise ScoValueError("Modification impossible: semestre verrouille") # -- check access # 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"]) ): 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 if ( 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"]) ): if raise_exc: diff --git a/app/scodoc/sco_moduleimpl_inscriptions.py b/app/scodoc/sco_moduleimpl_inscriptions.py index 0f12d38a0243724390179fa6ebb00854ebddfc11..11d8529ac807af8b2c03316cc6ddcc59089b23e4 100644 --- a/app/scodoc/sco_moduleimpl_inscriptions.py +++ b/app/scodoc/sco_moduleimpl_inscriptions.py @@ -278,9 +278,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id): set_all = set([x["etudid"] for x in inscrits]) partitions, _ = sco_groups.get_formsemestre_groups(formsemestre_id) - can_change = ( - authuser.has_permission(Permission.ScoEtudInscrit) and formsemestre.etat - ) + can_change = authuser.has_permission(Permission.EtudInscrit) and formsemestre.etat # Décrit les inscriptions aux modules: commons = [] # modules communs a tous les etuds du semestre diff --git a/app/scodoc/sco_moduleimpl_status.py b/app/scodoc/sco_moduleimpl_status.py index 68c04f01292c3b24118edf24132568af794bc772..71f05ccc77336b442b62e66de97c4a2ce3439e5e 100644 --- a/app/scodoc/sco_moduleimpl_status.py +++ b/app/scodoc/sco_moduleimpl_status.py @@ -290,7 +290,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None): H.append( 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( 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) # Liens saisies absences seulement si permission et date courante dans le semestre - if ( - current_user.has_permission(Permission.ScoAbsChange) - and formsemestre.est_courant() - ): + if current_user.has_permission(Permission.AbsChange) and formsemestre.est_courant(): group_id = sco_groups.get_default_group(formsemestre_id) H.append( f""" diff --git a/app/scodoc/sco_page_etud.py b/app/scodoc/sco_page_etud.py index 4b62d3817689a6470af4438a45b6ced8c46d4b9f..07ea62519eae70b1e6fbb4f660508ebec4008ab8 100644 --- a/app/scodoc/sco_page_etud.py +++ b/app/scodoc/sco_page_etud.py @@ -70,8 +70,8 @@ def _menu_scolarite( lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") return lockicon # no menu if not authuser.has_permission( - Permission.ScoEtudInscrit - ) and not authuser.has_permission(Permission.ScoEtudChangeGroups): + Permission.EtudInscrit + ) and not authuser.has_permission(Permission.EtudChangeGroups): return "" # no menu args = {"etudid": etudid, "formsemestre_id": formsemestre.id} @@ -92,7 +92,7 @@ def _menu_scolarite( def_url = "scolar.do_cancel_def" def_enabled = ( (etat_inscription != scu.DEMISSION) - and authuser.has_permission(Permission.ScoEtudInscrit) + and authuser.has_permission(Permission.EtudInscrit) and not locked ) items = [ @@ -100,15 +100,13 @@ def _menu_scolarite( "title": dem_title, "endpoint": dem_url, "args": args, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit) - and not locked, + "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked, }, { "title": "Validation du semestre (jury)", "endpoint": "notes.formsemestre_validation_etud_form", "args": args, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit) - and not locked, + "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked, }, { "title": def_title, @@ -120,15 +118,13 @@ def _menu_scolarite( "title": "Inscrire à un module optionnel (ou au sport)", "endpoint": "notes.formsemestre_inscription_option", "args": args, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit) - and not locked, + "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked, }, { "title": "Désinscrire (en cas d'erreur)", "endpoint": "notes.formsemestre_desinscription", "args": args, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit) - and not locked, + "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked, }, { "title": "Gérer les validations d'UEs antérieures", @@ -140,19 +136,19 @@ def _menu_scolarite( "title": "Inscrire à un autre semestre", "endpoint": "notes.formsemestre_inscription_with_modules_form", "args": {"etudid": etudid}, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit), + "enabled": authuser.has_permission(Permission.EtudInscrit), }, { "title": "Enregistrer un semestre effectué ailleurs", "endpoint": "notes.formsemestre_ext_create_form", "args": args, - "enabled": authuser.has_permission(Permission.ScoImplement), + "enabled": authuser.has_permission(Permission.EditFormSemestre), }, { "title": "Affecter les notes manquantes", "endpoint": "notes.formsemestre_note_etuds_sans_notes", "args": args, - "enabled": authuser.has_permission(Permission.ScoEditAllNotes), + "enabled": authuser.has_permission(Permission.EditAllNotes), }, ] @@ -235,7 +231,7 @@ def ficheEtud(etudid=None): else: info["emaillink"] = "<em>(pas d'adresse e-mail)</em>" # Champ dépendant des permissions: - if authuser.has_permission(Permission.ScoEtudChangeAdr): + if authuser.has_permission(Permission.EtudChangeAdr): info[ "modifadresse" ] = f"""<a class="stdlink" href="{ @@ -333,7 +329,7 @@ def ficheEtud(etudid=None): }">Visualiser les compétences BUT</a> </span> """ - if authuser.has_permission(Permission.ScoEtudInscrit): + if authuser.has_permission(Permission.EtudInscrit): info[ "link_inscrire_ailleurs" ] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{ @@ -351,7 +347,7 @@ def ficheEtud(etudid=None): else: # non inscrit 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( f"""<a href="{ url_for("notes.formsemestre_inscription_with_modules_form", @@ -634,25 +630,25 @@ def menus_etud(etudid): "title": "Changer la photo", "endpoint": "scolar.form_change_photo", "args": {"etudid": etud["etudid"]}, - "enabled": authuser.has_permission(Permission.ScoEtudChangeAdr), + "enabled": authuser.has_permission(Permission.EtudChangeAdr), }, { "title": "Changer les données identité/admission", "endpoint": "scolar.etudident_edit_form", "args": {"etudid": etud["etudid"]}, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit), + "enabled": authuser.has_permission(Permission.EtudInscrit), }, { "title": "Copier dans un autre département...", "endpoint": "scolar.etud_copy_in_other_dept", "args": {"etudid": etud["etudid"]}, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit), + "enabled": authuser.has_permission(Permission.EtudInscrit), }, { "title": "Supprimer cet étudiant...", "endpoint": "scolar.etudident_delete", "args": {"etudid": etud["etudid"]}, - "enabled": authuser.has_permission(Permission.ScoEtudInscrit), + "enabled": authuser.has_permission(Permission.EtudInscrit), }, { "title": "Voir le journal...", diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py index dd402548abd3eaa96296101146428f4e72707b20..5fa68a352d2ba872bb191fb062b74fb7190a3fcc 100644 --- a/app/scodoc/sco_permissions.py +++ b/app/scodoc/sco_permissions.py @@ -14,51 +14,51 @@ _SCO_PERMISSIONS = ( # - tous rôles lors creation utilisateurs (1 << 1, "ScoSuperAdmin", "Super Administrateur"), (1 << 2, "ScoView", "Voir"), - (1 << 3, "ScoEnsView", "Voir les parties pour les enseignants"), - (1 << 4, "ScoObservateur", "Observer (accès lecture restreint aux bulletins)"), - (1 << 5, "ScoUsersAdmin", "Gérer les utilisateurs (de son département)"), - (1 << 6, "ScoUsersView", "Voir les utilisateurs (de tous les dépts)"), - (1 << 7, "ScoChangePreferences", "Modifier les préférences"), - (1 << 8, "ScoChangeFormation", "Changer les formations"), - (1 << 9, "ScoEditFormationTags", "Tagguer les formations"), - (1 << 10, "ScoEditAllNotes", "Modifier toutes les notes"), - (1 << 11, "ScoEditAllEvals", "Modifier toutes les evaluations"), - (1 << 12, "ScoImplement", "Mettre en place une formation (créer un semestre)"), - (1 << 13, "ScoAbsChange", "Saisir des absences"), - (1 << 14, "ScoAbsAddBillet", "Saisir des billets d'absences"), + (1 << 3, "EnsView", "Voir les parties pour les enseignants"), + (1 << 4, "Observateur", "Observer (accès lecture restreint aux bulletins)"), + (1 << 5, "UsersAdmin", "Gérer les utilisateurs (de son département)"), + (1 << 6, "UsersView", "Voir les utilisateurs (de tous les dépts)"), + (1 << 7, "EditPreferences", "Modifier les préférences"), + (1 << 8, "EditFormation", "Changer les formations"), + (1 << 9, "EditFormationTags", "Tagguer les formations"), + (1 << 10, "EditAllNotes", "Modifier toutes les notes"), + (1 << 11, "EditAllEvals", "Modifier toutes les evaluations"), + (1 << 12, "EditFormSemestre", "Mettre en place une formation (créer un semestre)"), + (1 << 13, "AbsChange", "Saisir des absences"), + (1 << 14, "AbsAddBillet", "Saisir des billets d'absences"), # 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, "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: - (1 << 17, "ScoEtudInscrit", "Inscrire des étudiants"), + (1 << 17, "EtudInscrit", "Inscrire des étudiants"), # aussi pour archives: - (1 << 18, "ScoEtudAddAnnotations", "Éditer les annotations"), - (1 << 19, "ScoEntrepriseView", "Voir la section 'entreprises'"), - (1 << 20, "ScoEntrepriseChange", "Modifier les entreprises"), - (1 << 21, "ScoEditPVJury", "Éditer les PV de jury"), + (1 << 18, "EtudAddAnnotations", "Éditer les annotations"), + # inutilisée (1 << 19, "ScoEntrepriseView", "Voir la section 'entreprises'"), + # inutilisée (1 << 20, "EntrepriseChange", "Modifier les entreprises"), + # XXX inutilisée ? (1 << 21, "EditPVJury", "Éditer les PV de jury"), # 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 - (1 << 23, "RelationsEntreprisesView", "Voir l'application relations entreprises"), - (1 << 24, "RelationsEntreprisesChange", "Modifier les entreprises"), - (1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"), - (1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"), - (1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"), + (1 << 23, "RelationsEntrepView", "Voir l'application relations entreprises"), + (1 << 24, "RelationsEntrepEdit", "Modifier les entreprises"), + (1 << 25, "RelationsEntrepSend", "Envoyer des offres"), + (1 << 26, "RelationsEntrepValidate", "Valide les entreprises"), + (1 << 27, "RelationsEntrepViewCorrs", "Voir les correspondants"), ( 1 << 28, - "RelationsEntreprisesExport", + "RelationsEntrepExport", "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é) - (1 << 50, "ScoJustifView", "Visualisation des fichiers justificatifs"), + (1 << 50, "AbsJustifView", "Visualisation des fichiers justificatifs"), # Attention: les permissions sont codées sur 64 bits. ) diff --git a/app/scodoc/sco_permissions_check.py b/app/scodoc/sco_permissions_check.py index 1b6b368182190312dc30650620a1cfe55b559369..2d9e39c6a6aff8c92acbfbbe05d8e7e4ba71ecca 100644 --- a/app/scodoc/sco_permissions_check.py +++ b/app/scodoc/sco_permissions_check.py @@ -35,12 +35,12 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True): if sco_cursus_dut.formsemestre_has_decisions(sem["formsemestre_id"]): # il y a des décisions de jury dans ce semestre ! return ( - authuser.has_permission(Permission.ScoEditAllNotes) + authuser.has_permission(Permission.EditAllNotes) or authuser.id in sem["responsables"] ) else: if ( - (not authuser.has_permission(Permission.ScoEditAllNotes)) + (not authuser.has_permission(Permission.EditAllNotes)) and authuser.id != M["responsable_id"] and authuser.id not in sem["responsables"] ): @@ -65,27 +65,29 @@ def can_suppress_annotation(annotation_id): raise sco_exceptions.ScoValueError("annotation inexistante !") anno = annos[0] return (current_user.user_name == anno["author"]) or current_user.has_permission( - Permission.ScoEtudAddAnnotations + Permission.EtudAddAnnotations ) def can_edit_suivi(): """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 "Vrai si utilisateur est admin, chef dept ou responsable du semestre" if ( - current_user.has_permission(Permission.ScoImplement) + current_user.has_permission(Permission.EditFormSemestre) or current_user.id in sem["responsables"] ): return True return False -def check_access_diretud(formsemestre_id, required_permission=Permission.ScoImplement): - """Check if access granted: responsable or ScoImplement +def check_access_diretud( + formsemestre_id, required_permission=Permission.EditFormSemestre +): + """Check if access granted: responsable or EditFormSemestre Return True|False, HTML_error_page """ 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: return True # 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 # Now check that current_user can manage users from this departement if not current_user.dept: diff --git a/app/scodoc/sco_roles_default.py b/app/scodoc/sco_roles_default.py index 28d2be9c44833e59f20fb2f8538879709cbcc052..75cbdedd3639eecd1322666e2d6a6f4102affe2d 100644 --- a/app/scodoc/sco_roles_default.py +++ b/app/scodoc/sco_roles_default.py @@ -7,77 +7,72 @@ from app.scodoc.sco_permissions import Permission as p SCO_ROLES_DEFAULTS = { - "Observateur": (p.ScoObservateur,), "Ens": ( - p.ScoAbsAddBillet, - p.ScoAbsChange, - p.ScoEnsView, - p.ScoEntrepriseView, - p.ScoEtudAddAnnotations, - p.ScoObservateur, - p.ScoUsersView, + p.AbsAddBillet, + p.AbsChange, + p.EnsView, + p.EtudAddAnnotations, + p.Observateur, + p.UsersView, p.ScoView, ), "Secr": ( - p.ScoAbsAddBillet, - p.ScoAbsChange, - p.ScoEditApo, - p.ScoEntrepriseChange, - p.ScoEntrepriseView, - p.ScoEtudAddAnnotations, - p.ScoEtudChangeAdr, - p.ScoObservateur, - p.ScoUsersView, + p.AbsAddBillet, + p.AbsChange, + p.EditApogee, + p.EtudAddAnnotations, + p.EtudChangeAdr, + p.Observateur, + p.UsersView, p.ScoView, ), # Admin est le chef du département, pas le "super admin" # on doit donc lister toutes ses permissions: "Admin": ( - p.ScoAbsAddBillet, - p.ScoAbsChange, - p.ScoChangeFormation, - p.ScoChangePreferences, - p.ScoEditAllEvals, - p.ScoEditAllNotes, - p.ScoEditApo, - p.ScoEditFormationTags, - p.ScoEnsView, - p.ScoEntrepriseChange, - p.ScoEntrepriseView, - p.ScoEtudAddAnnotations, - p.ScoEtudChangeAdr, - p.ScoEtudChangeGroups, - p.ScoEtudInscrit, - p.ScoImplement, - p.ScoObservateur, - p.ScoUsersAdmin, - p.ScoUsersView, + p.AbsAddBillet, + p.AbsChange, + p.EditFormation, + p.EditPreferences, + p.EditAllEvals, + p.EditAllNotes, + p.EditApogee, + p.EditFormationTags, + p.EnsView, + p.EtudAddAnnotations, + p.EtudChangeAdr, + p.EtudChangeGroups, + p.EtudInscrit, + p.EditFormSemestre, + p.Observateur, + p.UsersAdmin, + p.UsersView, 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 # 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": ( - p.RelationsEntreprisesView, - p.RelationsEntreprisesChange, - p.RelationsEntreprisesCorrespondants, + p.RelationsEntrepView, + p.RelationsEntrepEdit, + p.RelationsEntrepViewCorrs, ), # AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application) "AdminEntreprise": ( - p.RelationsEntreprisesView, - p.RelationsEntreprisesChange, - p.RelationsEntreprisesExport, - p.RelationsEntreprisesSend, - p.RelationsEntreprisesValidate, - p.RelationsEntreprisesCorrespondants, + p.RelationsEntrepView, + p.RelationsEntrepEdit, + p.RelationsEntrepExport, + p.RelationsEntrepSend, + p.RelationsEntrepValidate, + p.RelationsEntrepViewCorrs, ), # LecteurAPI peut utiliser l'API en lecture "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 # _tous_ les droits # Afin d'avoir tous les droits, il ne doit pas être asscoié à un département diff --git a/app/scodoc/sco_synchro_etuds.py b/app/scodoc/sco_synchro_etuds.py index 6b1d8908ae34c6361f196fbc2d19085eca8dca87..16d1620da06248c60ece2e576dc8cbe2fa8361a9 100644 --- a/app/scodoc/sco_synchro_etuds.py +++ b/app/scodoc/sco_synchro_etuds.py @@ -92,7 +92,7 @@ def formsemestre_synchro_etuds( sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem["etape_apo_str"] = sco_formsemestre.formsemestre_etape_apo_str(sem) # Write access ? - if not current_user.has_permission(Permission.ScoEtudInscrit): + if not current_user.has_permission(Permission.EtudInscrit): read_only = True if read_only: submitted = False diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py index 07177a66213c781dcc4b8ba786f65930ce6cd55f..69f6103dc98828505bbaea0f0c3822dee161316a 100644 --- a/app/scodoc/sco_ue_external.py +++ b/app/scodoc/sco_ue_external.py @@ -92,7 +92,7 @@ def external_ue_create( log(f"creating external UE in {formsemestre}: {acronyme}") # 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 ( current_user.id not in [u.id for u in formsemestre.responsables] ): diff --git a/app/scodoc/sco_users.py b/app/scodoc/sco_users.py index 8492dcff92062c2ab691947d9218b50b7fe4f1f8..a102700a54b1ba62e1b8e3e2e978f5e176402ffb 100644 --- a/app/scodoc/sco_users.py +++ b/app/scodoc/sco_users.py @@ -56,7 +56,7 @@ def index_html( 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( f"""<p><a href="{url_for("users.create_user_form", scodoc_dept=g.scodoc_dept) @@ -118,7 +118,7 @@ def index_html( fmt=fmt, having_role=having_role, 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": return content diff --git a/app/static/css/role_editor.css b/app/static/css/role_editor.css index 2c3d87dcb6e28c64ec8f0e8666a9c8b0324cab7d..97d49f133d583efdac8f651c2aa276891280cb14 100644 --- a/app/static/css/role_editor.css +++ b/app/static/css/role_editor.css @@ -3,15 +3,51 @@ margin-bottom: 24px; } -section#roles { +.roles-editor { background-color: #fffaf4; + border-radius: 8px; + font-size: 90%; + margin-bottom: 24px; + padding: 8px; } -.role { +.re-row { + /* align-items: center; */ display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; 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 { @@ -26,8 +62,8 @@ section#roles { } .role input:checked:not([value=aucun])+span { - background: rgb(165, 6, 59); - border-color: rgb(165, 6, 59); + background: rgb(0, 141, 42); + border-color: rgb(0, 141, 42); color: #fff; } diff --git a/app/templates/auth/user_info_page.j2 b/app/templates/auth/user_info_page.j2 index a7bb02f4ecb9b27a7f91ff64a06e8b2d29011a39..ff008361eabd8d73b1b4298121af188f4e825571 100644 --- a/app/templates/auth/user_info_page.j2 +++ b/app/templates/auth/user_info_page.j2 @@ -42,7 +42,7 @@ <ul> {% if ( 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="{{ url_for( 'users.form_change_password', @@ -50,7 +50,7 @@ }}">modifier le mot de passe ou l'adresse mail</a> </li> {% endif %} - {% if current_user.has_permission(Permission.ScoUsersAdmin, dept) %} + {% if current_user.has_permission(Permission.UsersAdmin, dept) %} <li><a class="stdlink" href="{{ url_for('users.create_user_form', scodoc_dept=g.scodoc_dept, user_name=user.user_name, edit=1) @@ -59,7 +59,7 @@ {% endif %} {% if ( 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="{{ url_for('users.toggle_active_user', scodoc_dept=g.scodoc_dept, @@ -96,7 +96,7 @@ </ul> </div> -{% if current_user.has_permission(Permission.ScoUsersAdmin, dept) %} +{% if current_user.has_permission(Permission.UsersAdmin, dept) %} <p><a class="stdlink" href=" {{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}} ">Liste de tous les utilisateurs</a></p> diff --git a/app/templates/base.j2 b/app/templates/base.j2 index e4c796dfc87218b7b746b321df42cd1b70450577..570655f368102df8654058d20e080596f0063575 100644 --- a/app/templates/base.j2 +++ b/app/templates/base.j2 @@ -37,7 +37,7 @@ }}">Dept. {{ g.scodoc_dept }}</a></li> {% endif %} {% 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() %} <li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li> {% endif %} diff --git a/app/templates/but/parcour_formation.j2 b/app/templates/but/parcour_formation.j2 index f040d71128a253066f93eb3c3805a24caa6ae894..c80a38b2cf018529a205caff1901ee8ebfc0a5f5 100644 --- a/app/templates/but/parcour_formation.j2 +++ b/app/templates/but/parcour_formation.j2 @@ -8,7 +8,7 @@ {% macro menu_ue(niv, sem="pair", sem_idx=0) -%} {% 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}}" onchange="assoc_ue_niveau(event, {{niv['niveau'].id}}, {{parcour.id}} diff --git a/app/templates/entreprises/_correspondant.j2 b/app/templates/entreprises/_correspondant.j2 index 7d1539b72a135605e9ae3abc224846a267a99eff..e3e42f2eb37680723093c9c0c2a5e1ffb9157c54 100644 --- a/app/templates/entreprises/_correspondant.j2 +++ b/app/templates/entreprises/_correspondant.j2 @@ -24,7 +24,7 @@ {% endif %} </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"> <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> diff --git a/app/templates/entreprises/_offre.j2 b/app/templates/entreprises/_offre.j2 index 188cb692d2d48c7827888b0f94ff50d68db4b02d..c1a4d019880e52ae443e15e7ca4fc40e5179697a 100644 --- a/app/templates/entreprises/_offre.j2 +++ b/app/templates/entreprises/_offre.j2 @@ -22,28 +22,28 @@ {% 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> - {% 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> {% endif %} <br> {% 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> {% endif %} </div> <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-danger" href="{{ url_for('entreprises.delete_offre', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Supprimer l'offre</a> {% 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> {% 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 %} <a class="btn btn-danger" href="{{ url_for('entreprises.expired', entreprise_id=offre.entreprise_id, offre_id=offre.id) }}">Rendre expirée</a> {% else %} diff --git a/app/templates/entreprises/contacts.j2 b/app/templates/entreprises/contacts.j2 index 2180a01153097c3008d4904540bb5fcd830bb99d..490d4bb698ce186e619a7ba87feea2299186a269 100644 --- a/app/templates/entreprises/contacts.j2 +++ b/app/templates/entreprises/contacts.j2 @@ -26,7 +26,7 @@ <div class="container" style="margin-bottom: 10px;"> <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;" href="{{ url_for('entreprises.add_contact', entreprise_id=entreprise.id) }}">Ajouter contact</a> {% endif %} @@ -36,7 +36,7 @@ <td data-priority="">Date</td> <td data-priority="">Utilisateur</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> {% endif %} </tr> @@ -47,7 +47,7 @@ <td>{{ contact.date.strftime('%d/%m/%Y %Hh%M') }}</td> <td>{{ contact.user|get_nomcomplet_by_id }}</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> <div class="btn-group"> <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action @@ -71,7 +71,7 @@ <td>Date</td> <td>Utilisateur</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> {% endif %} </tr> diff --git a/app/templates/entreprises/entreprises.j2 b/app/templates/entreprises/entreprises.j2 index 9f4f7f24ac3c071a3aac5ea8d31da2d6d7e71920..5aa05b0bc17a70b15653d2b706baab9756213dd3 100644 --- a/app/templates/entreprises/entreprises.j2 +++ b/app/templates/entreprises/entreprises.j2 @@ -24,13 +24,13 @@ {% endif %} <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> {% 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> {% 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> {% endif %} </div> @@ -57,7 +57,7 @@ <td data-priority="6">Code postal</td> <td data-priority="5">Ville</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> {% endif %} </tr> @@ -73,7 +73,7 @@ <td>{{ entreprise.codepostal }}</td> <td>{{ entreprise.ville }}</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> <div class="btn-group"> <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action @@ -105,7 +105,7 @@ <td>Code postal</td> <td>Ville</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> {% endif %} </tr> diff --git a/app/templates/entreprises/fiche_entreprise.j2 b/app/templates/entreprises/fiche_entreprise.j2 index 66a64f64c518cd4fdf16f32d749dbb939216640a..e2c0da71ab1859b663e10a54158bb7d76cca830a 100644 --- a/app/templates/entreprises/fiche_entreprise.j2 +++ b/app/templates/entreprises/fiche_entreprise.j2 @@ -60,7 +60,7 @@ {% endif %} </div> - {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} + {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %} <div> Taxe d'apprentissage<br> <a class="btn btn-primary" @@ -90,7 +90,7 @@ </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" href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a> {% if entreprise.active %} @@ -123,7 +123,7 @@ Code postal : {{ site.codepostal }}<br> Ville : {{ site.ville }}<br> Pays : {{ site.pays }} - {% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %} + {% if current_user.has_permission(current_user.Permission.RelationsEntrepEdit, None) %} <div> <a class="btn btn-primary" href="{{ url_for('entreprises.edit_site', entreprise_id=entreprise.id, site_id=site.id) }}">Modifier</a> @@ -132,7 +132,7 @@ correspondant</a> </div> {% 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 %} {% include 'entreprises/_correspondant.j2' %} {% endfor %} @@ -156,7 +156,7 @@ <div style="margin-bottom: 10px;"> <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) }}" style="margin-bottom:10px;">Ajouter stage ou apprentissage</a> {% endif %} @@ -170,7 +170,7 @@ <td data-priority="1">Étudiant</td> <td data-priority="6">Formation</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> {% endif %} </tr> @@ -187,7 +187,7 @@ etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td> <td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</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> <div class="btn-group"> <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action @@ -215,7 +215,7 @@ <td>Étudiant</td> <td>Formation</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> {% endif %} </tr> diff --git a/app/templates/entreprises/fiche_entreprise_validation.j2 b/app/templates/entreprises/fiche_entreprise_validation.j2 index e67c7bf71a4634eca0118dc3aa6c61b13f84b572..2200c84427b9b0a1bd02583621909ea5cdd40f88 100644 --- a/app/templates/entreprises/fiche_entreprise_validation.j2 +++ b/app/templates/entreprises/fiche_entreprise_validation.j2 @@ -41,7 +41,7 @@ Code postal : {{ site.codepostal }}<br> Ville : {{ site.ville }}<br> 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 %} <div class="correspondant"> <div> diff --git a/app/templates/entreprises/nav.j2 b/app/templates/entreprises/nav.j2 index 0e84c5086951c0da62c59ffaf17ac55496c60637..5e9dd4335cbe870b1dd90405530691e60278bc8c 100644 --- a/app/templates/entreprises/nav.j2 +++ b/app/templates/entreprises/nav.j2 @@ -6,7 +6,7 @@ <a href="{{ url_for('entreprises.index') }}" class="nav_entreprise_link {% if title=='Entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises</a> </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"> <a href="{{ url_for('entreprises.correspondants') }}" class="nav_entreprise_link {% if title=='Correspondants' %}nav_entreprise_link-active{% endif %}">Correspondants</a> </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> </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"> <a href="{{ url_for('entreprises.validation') }}" class="nav_entreprise_link {% if title=='Validation entreprises' %}nav_entreprise_link-active{% endif %}">Entreprises à valider</a> </li> diff --git a/app/templates/entreprises/form_confirmation.j2 b/app/templates/form_confirmation.j2 similarity index 87% rename from app/templates/entreprises/form_confirmation.j2 rename to app/templates/form_confirmation.j2 index f29930c2a9ab7dfd55a9197882ea191af67d0013..47b6d315c0c551ddf1e1d851e7082ca8f5d10a4f 100644 --- a/app/templates/entreprises/form_confirmation.j2 +++ b/app/templates/form_confirmation.j2 @@ -5,7 +5,7 @@ {% block app_content %} <h1>{{ title }}</h1> <br> -<div>{{ info_message }}</div> +<div>{{ info_message | safe }}</div> <br> <div class="row"> <div class="col-md-4"> diff --git a/app/templates/main/index.j2 b/app/templates/main/index.j2 index f02aabbe51bb907faa19e2a5b59b7012e0e5f989..9298d86b8ff92edeef42ff5def3fe791ae111a08 100644 --- a/app/templates/main/index.j2 +++ b/app/templates/main/index.j2 @@ -39,7 +39,7 @@ <li><a href="ScoDoc/RT/Scolarite/Notes/essai"><tt>Notes/essai</tt> : test "notes", url manuelle</a></li> <li><a href="{{ url_for('notes.essai2' , scodoc_dept='RT') }}"><tt>Notes/essai2</tt></a> : permission - ScoImplement dans RT + EditFormSemestre dans RT </li> </ul> <h3>Essais décorateurs et appels</h3> diff --git a/app/templates/role_editor.j2 b/app/templates/role_editor.j2 deleted file mode 100644 index bc4ea948ffba4b84f6d93bf9031d975ae52f26d0..0000000000000000000000000000000000000000 --- a/app/templates/role_editor.j2 +++ /dev/null @@ -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 %} \ No newline at end of file diff --git a/app/templates/sco_value_error.j2 b/app/templates/sco_value_error.j2 index e9dbd86f9037ba691800d74bdbb8b01246f903b5..027e6aa682cd607fb0585a9dda8e45dcbeb5220c 100644 --- a/app/templates/sco_value_error.j2 +++ b/app/templates/sco_value_error.j2 @@ -7,13 +7,15 @@ {{ exc | safe }} -<p> +<div style="margin-top: 16px;"> {% if g.scodoc_dept %} <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 %} - <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 %} -</p> +</div> <p style="margin-top: 32px;" class="help"> Si le problème persiste, merci de contacter le support ScoDoc via diff --git a/app/templates/scodoc/permission_info.j2 b/app/templates/scodoc/permission_info.j2 new file mode 100644 index 0000000000000000000000000000000000000000..bf2bf3755e9565792f9d2d11676e74d51a98358f --- /dev/null +++ b/app/templates/scodoc/permission_info.j2 @@ -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 %} \ No newline at end of file diff --git a/app/templates/scodoc/role_create.j2 b/app/templates/scodoc/role_create.j2 new file mode 100644 index 0000000000000000000000000000000000000000..9c21b5d686d13e0df7604e1cdbaf39068e770309 --- /dev/null +++ b/app/templates/scodoc/role_create.j2 @@ -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 %} \ No newline at end of file diff --git a/app/templates/scodoc/role_editor.j2 b/app/templates/scodoc/role_editor.j2 new file mode 100644 index 0000000000000000000000000000000000000000..9656291ca835c007cd16b71a5c3514a1f91627d3 --- /dev/null +++ b/app/templates/scodoc/role_editor.j2 @@ -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 %} \ No newline at end of file diff --git a/app/templates/scodoc/role_info.j2 b/app/templates/scodoc/role_info.j2 new file mode 100644 index 0000000000000000000000000000000000000000..690ea0665632d71f7ea578c6d3794b91a0f9a75f --- /dev/null +++ b/app/templates/scodoc/role_info.j2 @@ -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 %} \ No newline at end of file diff --git a/app/templates/sidebar.j2 b/app/templates/sidebar.j2 index 90c3ad0420d65bb096fc6ba62b2a459097cfef0d..95bb93cd678dab4fd9c3432ae907bd084e1c1b98 100755 --- a/app/templates/sidebar.j2 +++ b/app/templates/sidebar.j2 @@ -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('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> {% endif %} - {% if current_user.has_permission(sco.Permission.ScoUsersAdmin) - or current_user.has_permission(sco.Permission.ScoUsersView) + {% if current_user.has_permission(sco.Permission.UsersAdmin) + 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 /> {% 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> {% endif %} {# /sidebar_common #} @@ -61,7 +61,7 @@ <br />{{sco.nbabsjust}} J., {{sco.nbabsnj}} N.J.</span> {% endif %} <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, etudid=sco.etud.id) }}">Ajouter</a></li> <li><a href="{{ url_for('assiduites.ajout_justificatif_etud', scodoc_dept=g.scodoc_dept, diff --git a/app/views/absences.py b/app/views/absences.py index 0edc56cd2be36dab9d41858ef1afa42311ada873..fe9cc8f79d59f2251d563822dc33db3fb391fb9d 100644 --- a/app/views/absences.py +++ b/app/views/absences.py @@ -83,7 +83,7 @@ def index_html(): ), ] if current_user.has_permission( - Permission.ScoAbsChange + Permission.AbsChange ) and sco_preferences.get_preference("handle_billets_abs"): H.append( f""" @@ -100,7 +100,7 @@ def index_html(): # ----- 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 @scodoc -@permission_required_compat_scodoc7(Permission.ScoAbsAddBillet) +@permission_required_compat_scodoc7(Permission.AbsAddBillet) @scodoc7func def AddBilletAbsence( begin, @@ -152,7 +152,7 @@ def AddBilletAbsence( @bp.route("/add_billets_absence_form", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoAbsAddBillet) +@permission_required(Permission.AbsAddBillet) @scodoc7func def add_billets_absence_form(etudid): """Formulaire ajout billet (pour tests seulement, le vrai @@ -272,7 +272,7 @@ def list_billets(): @bp.route("/delete_billets_absence", methods=["POST", "GET"]) @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) @scodoc7func def delete_billets_absence(billet_id, dialog_confirmed=False): """Supprime un billet.""" @@ -333,7 +333,7 @@ def _ProcessBilletAbsence( @bp.route("/process_billet_absence_form", methods=["POST", "GET"]) @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) @scodoc7func def process_billet_absence_form(billet_id: int): """Formulaire traitement d'un billet""" diff --git a/app/views/assiduites.py b/app/views/assiduites.py index f9a579d5a9d5e97c84500f301b06a01c33553ef0..a7c8b1dc5e685044aa6284ededa314a1328d2583 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -157,7 +157,7 @@ class HTMLBuilder: @bp.route("/") @bp.route("/BilanDept") @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def bilan_dept(): """Gestionnaire assiduités, page principale""" H = [ @@ -185,7 +185,7 @@ def bilan_dept(): ) H.append(sco_find_etud.form_search_etud(dest_url="assiduites.bilan_etud")) if current_user.has_permission( - Permission.ScoAbsChange + Permission.AbsChange ) and sco_preferences.get_preference("handle_billets_abs"): H.append( f""" @@ -275,7 +275,7 @@ def bilan_dept(): @bp.route("/SignaleAssiduiteEtud") @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def signal_assiduites_etud(): """ signal_assiduites_etud Saisie de l'assiduité d'un étudiant @@ -477,7 +477,7 @@ def bilan_etud(): @bp.route("/AjoutJustificatifEtud") @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def ajout_justificatif_etud(): """ ajout_justificatif_etud : Affichage et création/modification des justificatifs de l'étudiant @@ -579,7 +579,7 @@ def calendrier_etud(): @bp.route("/SignalAssiduiteGr") @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def signal_assiduites_group(): """ 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") @scodoc -@permission_required(Permission.ScoAbsChange) +@permission_required(Permission.AbsChange) def signal_assiduites_diff(): group_ids: list[int] = request.args.get("group_ids", None) formsemestre_id: int = request.args.get("formsemestre_id", -1) diff --git a/app/views/but_formation.py b/app/views/but_formation.py index 64e4d90af93ee60a1665c129b686497b3b91cecb..8cbbedc619cedeec5e20bfe1c295e8fbdcd86ea1 100644 --- a/app/views/but_formation.py +++ b/app/views/but_formation.py @@ -120,7 +120,7 @@ def validation_rcues( @bp.route("/ue_parcours_ects/<int:ue_id>", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def ue_parcours_ects(ue_id: int): """formulaire (div) pour associer des ECTS par parcours d'une UE""" ue: UniteEns = ( diff --git a/app/views/notes.py b/app/views/notes.py index af1d011aff7dc85f7bccc30f5469e9e9f91d8e5d..d0063b6547df36ebe1de3d61be9786eb7c5100f6 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -185,7 +185,7 @@ sco_publish( sco_publish( "/formsemestre_createwithmodules", sco_formsemestre_edit.formsemestre_createwithmodules, - Permission.ScoImplement, + Permission.EditFormSemestre, methods=["GET", "POST"], ) @@ -200,25 +200,25 @@ sco_publish( sco_publish( "/formsemestre_clone", sco_formsemestre_edit.formsemestre_clone, - Permission.ScoImplement, + Permission.EditFormSemestre, methods=["GET", "POST"], ) sco_publish( "/formsemestre_associate_new_version", sco_formation_versions.formsemestre_associate_new_version, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/formsemestre_delete", sco_formsemestre_edit.formsemestre_delete, - Permission.ScoImplement, + Permission.EditFormSemestre, methods=["GET", "POST"], ) sco_publish( "/formsemestre_delete2", sco_formsemestre_edit.formsemestre_delete2, - Permission.ScoImplement, + Permission.EditFormSemestre, methods=["GET", "POST"], ) sco_publish( @@ -240,7 +240,7 @@ sco_publish( sco_publish( "/formsemestres_bulletins", sco_recapcomplet.formsemestres_bulletins, - Permission.ScoObservateur, + Permission.Observateur, ) sco_publish( "/moduleimpl_status", sco_moduleimpl_status.moduleimpl_status, Permission.ScoView @@ -254,19 +254,19 @@ sco_publish( sco_publish( "/formation_create", sco_edit_formation.formation_create, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/formation_delete", sco_edit_formation.formation_delete, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/formation_edit", sco_edit_formation.formation_edit, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) @@ -332,7 +332,7 @@ def formsemestre_bulletinetud( version=version, ), can_edit_appreciations=formsemestre.est_responsable(current_user) - or (current_user.has_permission(Permission.ScoEtudInscrit)), + or (current_user.has_permission(Permission.EtudInscrit)), etud=etud, formsemestre=formsemestre, inscription_courante=etud.inscription_courante(), @@ -429,26 +429,26 @@ sco_publish( sco_publish( "/ue_create", sco_edit_ue.ue_create, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/ue_delete", sco_edit_ue.ue_delete, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/ue_edit", sco_edit_ue.ue_edit, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) @bp.route("/set_ue_niveau_competence", methods=["POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def set_ue_niveau_competence(): """Associe UE et niveau. Si le niveau_id est "", désassocie.""" @@ -501,7 +501,7 @@ def ue_infos(ue_id): @bp.route("/ue_set_internal", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) @scodoc7func def ue_set_internal(ue_id): """""" @@ -541,7 +541,7 @@ def ue_sharing_code(): sco_publish( "/edit_ue_set_code_apogee", sco_edit_ue.edit_ue_set_code_apogee, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["POST"], ) sco_publish( @@ -568,48 +568,48 @@ sco_publish( sco_publish( "/formation_add_malus_modules", sco_edit_module.formation_add_malus_modules, - Permission.ScoChangeFormation, + Permission.EditFormation, ) sco_publish( "/matiere_create", sco_edit_matiere.matiere_create, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/matiere_delete", sco_edit_matiere.matiere_delete, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/matiere_edit", sco_edit_matiere.matiere_edit, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/module_create", sco_edit_module.module_create, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/module_delete", sco_edit_module.module_delete, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/module_edit", sco_edit_module.module_edit, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) sco_publish( "/edit_module_set_code_apogee", sco_edit_module.edit_module_set_code_apogee, - Permission.ScoChangeFormation, + Permission.EditFormation, methods=["GET", "POST"], ) 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"]) @scodoc -@permission_required(Permission.ScoEditFormationTags) +@permission_required(Permission.EditFormationTags) def module_tag_set(): """Set tags on module""" module_id = int(request.form.get("module_id")) @@ -628,7 +628,7 @@ def module_tag_set(): @bp.route("/module_clone", methods=["POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def module_clone(): """Clone existing module""" module_id = int(request.form.get("module_id")) @@ -656,7 +656,7 @@ def module_clone(): def index_html(): "Page accueil formations" - editable = current_user.has_permission(Permission.ScoChangeFormation) + editable = current_user.has_permission(Permission.EditFormation) H = [ 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"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) @scodoc7func def formation_import_xml_form(): "form import d'une formation en XML" @@ -790,7 +790,7 @@ def formation_import_xml_form(): # sco_publish( # "/formation_create_new_version", # sco_formations.formation_create_new_version, -# Permission.ScoChangeFormation, +# Permission.EditFormation, # ) # --- UE @@ -800,15 +800,13 @@ sco_publish( Permission.ScoView, ) -sco_publish( - "/module_move", sco_edit_formation.module_move, Permission.ScoChangeFormation -) -sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormation) +sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation) +sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.EditFormation) @bp.route("/ue_clone", methods=["POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def ue_clone(): """Clone existing UE""" ue_id = int(request.form.get("ue_id")) @@ -1380,12 +1378,12 @@ def edit_enseignants_form_delete(moduleimpl_id, ens_id: int): # sco_publish( # "/do_formsemestre_inscription_create", # sco_formsemestre_inscriptions.do_formsemestre_inscription_create, -# Permission.ScoEtudInscrit, +# Permission.EtudInscrit, # ) # sco_publish( # "/do_formsemestre_inscription_edit", # sco_formsemestre_inscriptions.do_formsemestre_inscription_edit, -# Permission.ScoEtudInscrit, +# Permission.EtudInscrit, # ) sco_publish( @@ -1409,7 +1407,7 @@ def do_formsemestre_inscription_listinscrits(formsemestre_id, fmt=None): @bp.route("/formsemestre_desinscription", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoImplement) +@permission_required(Permission.EditFormSemestre) @scodoc7func def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False): """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( "/do_formsemestre_desinscription", sco_formsemestre_inscriptions.do_formsemestre_desinscription, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, methods=["GET", "POST"], ) @@ -1503,7 +1501,7 @@ sco_publish( methods=["GET", "POST"], ) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) 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. @@ -1551,7 +1549,7 @@ def etud_desinscrit_ue(etudid, formsemestre_id, ue_id): methods=["GET", "POST"], ) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) def etud_inscrit_ue(etudid, formsemestre_id, ue_id): """ 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( "/formsemestre_inscription_with_modules_form", sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_form, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, ) sco_publish( "/formsemestre_inscription_with_modules_etud", sco_formsemestre_inscriptions.formsemestre_inscription_with_modules_etud, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, ) sco_publish( "/formsemestre_inscription_with_modules", sco_formsemestre_inscriptions.formsemestre_inscription_with_modules, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, ) sco_publish( "/formsemestre_inscription_option", sco_formsemestre_inscriptions.formsemestre_inscription_option, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, methods=["GET", "POST"], ) sco_publish( "/do_moduleimpl_incription_options", sco_formsemestre_inscriptions.do_moduleimpl_incription_options, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, ) sco_publish( "/formsemestre_inscrits_ailleurs", @@ -1623,7 +1621,7 @@ sco_publish( sco_publish( "/moduleimpl_inscriptions_edit", sco_moduleimpl_inscriptions.moduleimpl_inscriptions_edit, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, methods=["GET", "POST"], ) sco_publish( @@ -1638,7 +1636,7 @@ sco_publish( @bp.route("/evaluation_delete", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEnsView) +@permission_required(Permission.EnsView) @scodoc7func def evaluation_delete(evaluation_id): """Form delete evaluation""" @@ -1727,7 +1725,7 @@ def evaluation_delete(evaluation_id): @bp.route("/evaluation_edit", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEnsView) +@permission_required(Permission.EnsView) @scodoc7func def evaluation_edit(evaluation_id): "form edit evaluation" @@ -1738,7 +1736,7 @@ def evaluation_edit(evaluation_id): @bp.route("/evaluation_create", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEnsView) +@permission_required(Permission.EnsView) @scodoc7func def evaluation_create(moduleimpl_id): "form create evaluation" @@ -1816,7 +1814,7 @@ sco_publish( sco_publish( "/placement_eval_selectetuds", sco_placement.placement_eval_selectetuds, - Permission.ScoEnsView, + Permission.EnsView, methods=["GET", "POST"], ) @@ -1824,19 +1822,19 @@ sco_publish( sco_publish( "/saisie_notes_tableur", sco_saisie_notes.saisie_notes_tableur, - Permission.ScoEnsView, + Permission.EnsView, methods=["GET", "POST"], ) sco_publish( "/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( "/do_evaluation_set_missing", sco_saisie_notes.do_evaluation_set_missing, - Permission.ScoEnsView, + Permission.EnsView, methods=["GET", "POST"], ) sco_publish( @@ -2045,7 +2043,7 @@ sco_publish( @bp.route("/appreciation_add_form", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEnsView) +@permission_required(Permission.EnsView) @scodoc7func def appreciation_add_form( etudid=None, @@ -2073,7 +2071,7 @@ def appreciation_add_form( formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) # check custom access permission 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: 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"], ) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int): """Efface toute les décisions d'une année pour cet étudiant""" 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"], ) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) def jury_delete_manual(etudid: int): """Efface toute les décisions d'une année pour cet étudiant""" etud: Identite = Identite.query.get_or_404(etudid) @@ -2978,46 +2976,46 @@ sco_publish( sco_archives.formsemestre_get_archived_file, 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( "/view_apo_csv_store", sco_etape_apogee_view.view_apo_csv_store, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/view_apo_csv_download_and_store", sco_etape_apogee_view.view_apo_csv_download_and_store, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/view_apo_csv_delete", sco_etape_apogee_view.view_apo_csv_delete, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) 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( - "/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( "/apo_semset_maq_status", sco_etape_apogee_view.apo_semset_maq_status, - Permission.ScoEditApo, + Permission.EditApogee, ) sco_publish( "/apo_csv_export_results", sco_etape_apogee_view.apo_csv_export_results, - Permission.ScoEditApo, + Permission.EditApogee, ) @bp.route("/formsemestre_set_apo_etapes", methods=["POST"]) @scodoc -@permission_required(Permission.ScoEditApo) +@permission_required(Permission.EditApogee) def formsemestre_set_apo_etapes(): """Change les codes étapes du semestre indiqué. 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"]) @scodoc -@permission_required(Permission.ScoEditApo) +@permission_required(Permission.EditApogee) def formsemestre_set_elt_annee_apo(): """Change les codes étapes du semestre indiqué. 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"]) @scodoc -@permission_required(Permission.ScoEditApo) +@permission_required(Permission.EditApogee) def formsemestre_set_elt_sem_apo(): """Change les codes étapes du semestre indiqué. 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"]) @scodoc -@permission_required(Permission.ScoEditApo) +@permission_required(Permission.EditApogee) def ue_set_apo(): """Change le code APO de l'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"]) @scodoc -@permission_required(Permission.ScoEditApo) +@permission_required(Permission.EditApogee) def module_set_apo(): """Change le code APO du module Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE) @@ -3130,35 +3128,35 @@ def module_set_apo(): # sco_semset -sco_publish("/semset_page", sco_semset.semset_page, Permission.ScoEditApo) +sco_publish("/semset_page", sco_semset.semset_page, Permission.EditApogee) sco_publish( "/do_semset_create", sco_semset.do_semset_create, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/do_semset_delete", sco_semset.do_semset_delete, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/edit_semset_set_title", sco_semset.edit_semset_set_title, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/do_semset_add_sem", sco_semset.do_semset_add_sem, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) sco_publish( "/do_semset_remove_sem", sco_semset.do_semset_remove_sem, - Permission.ScoEditApo, + Permission.EditApogee, methods=["GET", "POST"], ) @@ -3166,7 +3164,7 @@ sco_publish( sco_publish( "/scodoc_table_results", sco_export_results.scodoc_table_results, - Permission.ScoEditApo, + Permission.EditApogee, ) sco_publish( @@ -3186,7 +3184,7 @@ sco_publish( sco_publish( "/formsemestre_inscr_passage", sco_inscr_passage.formsemestre_inscr_passage, - Permission.ScoEtudInscrit, + Permission.EtudInscrit, methods=["GET", "POST"], ) sco_publish( @@ -3258,7 +3256,7 @@ sco_publish( @bp.route("/check_sem_integrity") @scodoc -@permission_required(Permission.ScoImplement) +@permission_required(Permission.EditFormSemestre) @scodoc7func def check_sem_integrity(formsemestre_id, fix=False): """Debug. diff --git a/app/views/notes_formsemestre.py b/app/views/notes_formsemestre.py index e445d88439e30931211f66cdff8b21b54f146b35..843370422cef15880972e9bbadeedb2a48b7ad3f 100644 --- a/app/views/notes_formsemestre.py +++ b/app/views/notes_formsemestre.py @@ -48,7 +48,7 @@ from app.views import ScoData "/formsemestre_change_formation/<int:formsemestre_id>", methods=["GET", "POST"] ) @scodoc -@permission_required(Permission.ScoImplement) +@permission_required(Permission.EditFormSemestre) def formsemestre_change_formation(formsemestre_id: int): """Propose de changer un formsemestre de formation. Cette opération est bien sûr impossible... sauf si les deux formations sont identiques. diff --git a/app/views/pn_modules.py b/app/views/pn_modules.py index b3d302847ffe585085ff41a7333e9b3a60804d88..fdf6542ec6469da49c1e3d438722017a1edfb365 100644 --- a/app/views/pn_modules.py +++ b/app/views/pn_modules.py @@ -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"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def set_module_ue_coef(): """Set coef from module to UE""" try: @@ -234,7 +234,7 @@ def edit_modules_ue_coefs(): scodoc_dept=g.scodoc_dept, ), read_only=locked - or not current_user.has_permission(Permission.ScoChangeFormation), + or not current_user.has_permission(Permission.EditFormation), semestre_idx=semestre_idx, semestre_ids=range(1, formation.get_cursus().NB_SEM + 1), parcours_id=parcours_id, diff --git a/app/views/refcomp.py b/app/views/refcomp.py index a7f5edfb37ae2d6c5f69b517da0d541710af5013..f956bde78b04b0371b48fef51446b6cacfcd10ab 100644 --- a/app/views/refcomp.py +++ b/app/views/refcomp.py @@ -63,7 +63,7 @@ def refcomp_show(refcomp_id): @bp.route("/referentiel/comp/delete/<int:refcomp_id>", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def refcomp_delete(refcomp_id): """Suppression du référentiel de la base. Le fichier source n'est pas affecté.""" 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""" refs = ApcReferentielCompetences.query.filter_by(dept_id=g.scodoc_dept_id) 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 suppr_icon = scu.icontag( "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"] ) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def refcomp_assoc_formation(formation_id: int): """Formulaire association ref. compétence""" 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"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def refcomp_desassoc_formation(formation_id: int): """Désassocie la formation de son ref. de compétence""" 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"]) @scodoc -@permission_required(Permission.ScoChangeFormation) +@permission_required(Permission.EditFormation) def refcomp_load(formation_id=None): """Formulaire association ref. compétence""" if formation_id is not None: diff --git a/app/views/scodoc.py b/app/views/scodoc.py index ac499c5628ad7c63dda40eb384a6e01919915d1a..46dd8d8ff747ad1b341f80b004ea024cc466b094 100644 --- a/app/views/scodoc.py +++ b/app/views/scodoc.py @@ -60,12 +60,15 @@ from app.decorators import ( scodoc7func, scodoc, ) +from app.forms.generic import SimpleConfirmationForm from app.forms.main import config_logos, config_main from app.forms.main.config_assiduites import ConfigAssiduitesForm from app.forms.main.config_apo import CodesDecisionsForm from app.forms.main.config_cas import ConfigCASForm from app.forms.main.config_personalized_links import PersonalizedLinksForm from app.forms.main.create_dept import CreateDeptForm +from app.forms.main.role_create import CreateRoleForm + from app import models from app.models import ( 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_permissions import Permission +from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS from app.views import scodoc_bp as bp import sco_version @@ -151,10 +155,88 @@ def config_roles(): permissions_names = sorted(Permission.permission_by_value.values()) roles = Role.query.order_by(Role.name).all() return render_template( - "role_editor.j2", + "scodoc/role_editor.j2", Permission=Permission, permissions_names=permissions_names, 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>""", ) diff --git a/app/views/scolar.py b/app/views/scolar.py index 7d1cf2e258dfff2b39ffa742f3fb57bb9d921b30..c16c0a0d99744a69565f14ff081ea940fe61c30b 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -130,7 +130,7 @@ def sco_publish(route, function, permission, methods=["GET"]): @bp.route("/edit_preferences", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoChangePreferences) +@permission_required(Permission.EditPreferences) @scodoc7func def edit_preferences(): """Edit global preferences (lien "Paramétrage" département)""" @@ -145,7 +145,7 @@ def formsemestre_edit_preferences(formsemestre_id): """Edit preferences for a semestre""" sem = sco_formsemestre.get_formsemestre(formsemestre_id) 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"]) ) and (sem["etat"]) if ok: @@ -196,7 +196,7 @@ class DeptLogosConfigurationForm(FlaskForm): # @bp.route("/config_logos", methods=["GET", "POST"]) -# @permission_required(Permission.ScoChangePreferences) +# @permission_required(Permission.EditPreferences) # def config_logos(scodoc_dept): # "Panneau de configuration général" # form = DeptLogosConfigurationForm() @@ -256,7 +256,7 @@ class DeptLogosConfigurationForm(FlaskForm): # @bp.route("/config_logos", methods=["GET", "POST"]) -# @permission_required(Permission.ScoChangePreferences) +# @permission_required(Permission.EditPreferences) # def config_logos(scodoc_dept): # "Panneau de configuration général" # form = DeptLogosConfigurationForm() @@ -661,25 +661,25 @@ sco_publish( sco_publish( "/itemsuivi_suppress", sco_debouche.itemsuivi_suppress, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) sco_publish( "/itemsuivi_create", sco_debouche.itemsuivi_create, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) sco_publish( "/itemsuivi_set_date", sco_debouche.itemsuivi_set_date, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) sco_publish( "/itemsuivi_set_situation", sco_debouche.itemsuivi_set_situation, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) sco_publish( @@ -692,14 +692,14 @@ sco_publish( sco_publish( "/itemsuivi_tag_set", sco_debouche.itemsuivi_tag_set, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) @bp.route("/doAddAnnotation", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEtudAddAnnotations) +@permission_required(Permission.EtudAddAnnotations) @scodoc7func def doAddAnnotation(etudid, comment): "ajoute annotation sur etudiant" @@ -750,7 +750,7 @@ def doSuppressAnnotation(etudid, annotation_id): @bp.route("/form_change_coordonnees", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEtudChangeAdr) +@permission_required(Permission.EtudChangeAdr) @scodoc7func def form_change_coordonnees(etudid): "edit coordonnees etudiant" @@ -1014,7 +1014,7 @@ def etud_photo_orig_page(etudid=None): @bp.route("/form_change_photo", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEtudChangeAdr) +@permission_required(Permission.EtudChangeAdr) @scodoc7func def form_change_photo(etudid=None): """Formulaire changement photo étudiant""" @@ -1077,7 +1077,7 @@ def form_change_photo(etudid=None): @bp.route("/form_suppress_photo", methods=["POST", "GET"]) @scodoc -@permission_required(Permission.ScoEtudChangeAdr) +@permission_required(Permission.EtudChangeAdr) @scodoc7func def form_suppress_photo(etudid=None, dialog_confirmed=False): """Formulaire suppression photo étudiant""" @@ -1102,7 +1102,7 @@ def form_suppress_photo(etudid=None, dialog_confirmed=False): # @bp.route("/form_dem") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def form_dem(etudid, formsemestre_id): "Formulaire Démission Etudiant" @@ -1116,7 +1116,7 @@ def form_dem(etudid, formsemestre_id): @bp.route("/form_def") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def form_def(etudid, formsemestre_id): "Formulaire Défaillance Etudiant" @@ -1174,7 +1174,7 @@ def _form_dem_of_def( @bp.route("/do_dem_etudiant") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def do_dem_etudiant(etudid, formsemestre_id, event_date=None): "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") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def do_def_etudiant(etudid, formsemestre_id, event_date=None): "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"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def do_cancel_dem(etudid, formsemestre_id, dialog_confirmed=False, args=None): "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"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def do_cancel_def(etudid, formsemestre_id, dialog_confirmed=False, args=None): "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"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def etudident_create_form(): "formulaire creation individuelle etudiant" @@ -1335,7 +1335,7 @@ def etudident_create_form(): @bp.route("/etudident_edit_form", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def etudident_edit_form(): "formulaire edition individuelle etudiant" @@ -1778,7 +1778,7 @@ def _etudident_create_or_edit_form(edit): @scodoc @permission_required( 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): """Crée une copie de l'étudiant (avec ses adresses et codes) dans un autre département et l'inscrit à un formsemestre @@ -1797,7 +1797,7 @@ def etud_copy_in_other_dept(etudid: int): abort(404, description="formsemestre_id invalide") formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) if not current_user.has_permission( - Permission.ScoEtudInscrit, formsemestre.departement.acronym + Permission.EtudInscrit, formsemestre.departement.acronym ): raise ScoPermissionDenied("non autorisé") new_etud = etud.clone(new_dept_id=formsemestre.dept_id) @@ -1827,7 +1827,7 @@ def etud_copy_in_other_dept(etudid: int): departements = { dept.id: dept 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 } formsemestres_by_dept = { @@ -1847,7 +1847,7 @@ def etud_copy_in_other_dept(etudid: int): @bp.route("/etudident_delete", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def etudident_delete(etudid, dialog_confirmed=False): "Delete a student" @@ -1921,7 +1921,7 @@ def etudident_delete(etudid, dialog_confirmed=False): @bp.route("/check_group_apogee") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def check_group_apogee(group_id, etat=None, fix=False, fixmail=False): """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"]) @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def form_students_import_excel(formsemestre_id=None): "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") @scodoc -@permission_required(Permission.ScoEtudInscrit) +@permission_required(Permission.EtudInscrit) @scodoc7func def import_generate_excel_sample(with_codesemestre="1"): "une feuille excel pour importation etudiants" @@ -2256,7 +2256,7 @@ def form_students_import_infos_admissions(formsemestre_id=None): "formulaire import xls" authuser = current_user F = html_sco_header.sco_footer() - if not authuser.has_permission(Permission.ScoEtudInscrit): + if not authuser.has_permission(Permission.EtudInscrit): # autorise juste l'export H = [ html_sco_header.sco_header( @@ -2356,7 +2356,7 @@ def form_students_import_infos_admissions(formsemestre_id=None): @bp.route("/formsemestre_import_etud_admission") @scodoc -@permission_required(Permission.ScoEtudChangeAdr) +@permission_required(Permission.EtudChangeAdr) @scodoc7func def formsemestre_import_etud_admission(formsemestre_id, import_email=True): """Reimporte donnees admissions par synchro Portail Apogée""" @@ -2392,13 +2392,13 @@ def formsemestre_import_etud_admission(formsemestre_id, import_email=True): sco_publish( "/photos_import_files_form", sco_trombino.photos_import_files_form, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, methods=["GET", "POST"], ) sco_publish( "/photos_generate_excel_sample", sco_trombino.photos_generate_excel_sample, - Permission.ScoEtudChangeAdr, + Permission.EtudChangeAdr, ) diff --git a/app/views/users.py b/app/views/users.py index 144189fde637c01e9c6e75d7848231998d484149..6bf16f4dcd0d9a38602f34e08fff8876e586a1e7 100644 --- a/app/views/users.py +++ b/app/views/users.py @@ -133,7 +133,7 @@ class Mode(IntEnum): @bp.route("/") @bp.route("/index_html") @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @scodoc7func def index_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 courant peut administrer des utilisateurs. 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(): @@ -161,7 +161,7 @@ def _get_administrable_depts() -> list[str]: ) else: administrable_dept_acronyms = current_user.get_depts_with_permission( - Permission.ScoUsersAdmin + Permission.UsersAdmin ) if None in administrable_dept_acronyms: administrable_dept_acronyms = sorted( @@ -209,7 +209,7 @@ def _get_editable_roles( @bp.route("/create_user_form", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @scodoc7func def create_user_form(user_name=None, edit=0, all_roles=True): "form. création ou édition utilisateur" @@ -415,7 +415,7 @@ def create_user_form(user_name=None, edit=0, all_roles=True): "size": 36, "allow_null": True, "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 vals.pop("cas_allow_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) if "edit" in vals: 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") @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @scodoc7func def import_users_generate_excel_sample(): "une feuille excel pour importation utilisateurs" @@ -788,7 +788,7 @@ def import_users_generate_excel_sample(): @bp.route("/import_users_form", methods=["GET", "POST"]) @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) @scodoc7func def import_users_form(): """Import utilisateurs depuis feuille Excel""" @@ -884,7 +884,7 @@ def import_users_form(): @bp.route("/user_info_page") @scodoc -@permission_required(Permission.ScoUsersView) +@permission_required(Permission.UsersView) @scodoc7func def user_info_page(user_name=None): """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"]) @scodoc -@permission_required(Permission.ScoUsersAdmin) +@permission_required(Permission.UsersAdmin) def toggle_active_user(user_name: str = None): """Change active status of a user account""" if user_name is not None: # scodoc7func converti en int ! @@ -1082,7 +1082,7 @@ def toggle_active_user(user_name: str = None): # permission check: if not ( current_user.is_administrator() - or current_user.has_permission(Permission.ScoUsersAdmin, u.dept) + or current_user.has_permission(Permission.UsersAdmin, u.dept) ): raise ScoPermissionDenied() form = DeactivateUserForm() diff --git a/migrations/versions/57179ae34069_api_permissions.py b/migrations/versions/57179ae34069_api_permissions.py index 6ba58795497895dc671fce8ddaf422acf80024aa..ef0926bbd11213302c3f35b082e8bb308228ca8f 100644 --- a/migrations/versions/57179ae34069_api_permissions.py +++ b/migrations/versions/57179ae34069_api_permissions.py @@ -19,7 +19,7 @@ depends_on = None def upgrade(): # Modification des permissions API # APIView 1<<40 = 1099511627776 => ScoView = 4 - # APIEditGroups 1<<41 = 2199023255552 => ScoEtudChangeGroups = 1<<16 65536 + # APIEditGroups 1<<41 = 2199023255552 => EtudChangeGroups = 1<<16 65536 op.execute( """ update role set permissions = permissions | 4 where (permissions & 1099511627776) <> 0; diff --git a/scodoc.py b/scodoc.py index a897f29cad48e5c4558051b08f94a77fe9849473..e0a0e2f187d60a5eab8a00cbd517f6ecd1876834 100755 --- a/scodoc.py +++ b/scodoc.py @@ -289,7 +289,7 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e In ScoDoc, permissions are not associated to users but to roles. 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: perm_to_add = Permission.get_by_name(addpermissionname) diff --git a/tests/api/make_samples.py b/tests/api/make_samples.py index fab767919e38566257d6326c0848bb171a593796..09cc88c594cfe1853898b1611bb52bd7e28fe494 100644 --- a/tests/api/make_samples.py +++ b/tests/api/make_samples.py @@ -95,7 +95,7 @@ class Sample: HEADERS = get_auth_headers("test", "test") elif permission == "ScoSuperAdmin": HEADERS = get_auth_headers("admin_api", "admin_api") - elif permission == "ScoUsersAdmin": + elif permission == "UsersAdmin": HEADERS = get_auth_headers("admin_api", "admin_api") else: raise SampleException(f"Bad permission : {permission}") diff --git a/tests/api/test_api_permissions.py b/tests/api/test_api_permissions.py index 5a488a4bbe1f9400b5a2eceb40520ab5dd28064d..974e01874ae553393aaa3d9b568f315f54796250 100755 --- a/tests/api/test_api_permissions.py +++ b/tests/api/test_api_permissions.py @@ -85,7 +85,7 @@ def test_permissions(api_headers): "/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 continue diff --git a/tests/api/test_api_users.py b/tests/api/test_api_users.py index e0e0e579c46ae2adce875e69a0d56ee261b6aaf1..1421a29cf4710212cfd7235179c94169f92ff77b 100644 --- a/tests/api/test_api_users.py +++ b/tests/api/test_api_users.py @@ -125,16 +125,16 @@ def test_roles(api_admin_headers): assert role["role_name"] == "Test_Y" role = POST_JSON( "/role/Test_Y/edit", - {"permissions": ["ScoView", "ScoAbsChange"]}, + {"permissions": ["ScoView", "AbsChange"]}, headers=admin_h, ) - assert set(role["permissions"]) == {"ScoView", "ScoAbsChange"} - role = POST_JSON("/role/Test_Y/add_permission/ScoAbsAddBillet", headers=admin_h) - assert set(role["permissions"]) == {"ScoView", "ScoAbsChange", "ScoAbsAddBillet"} + assert set(role["permissions"]) == {"ScoView", "AbsChange"} + role = POST_JSON("/role/Test_Y/add_permission/AbsAddBillet", headers=admin_h) + assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"} role = GET("/role/Test_Y", headers=admin_h) - assert set(role["permissions"]) == {"ScoView", "ScoAbsChange", "ScoAbsAddBillet"} - role = POST_JSON("/role/Test_Y/remove_permission/ScoAbsChange", headers=admin_h) - assert set(role["permissions"]) == {"ScoView", "ScoAbsAddBillet"} + assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"} + role = POST_JSON("/role/Test_Y/remove_permission/AbsChange", headers=admin_h) + assert set(role["permissions"]) == {"ScoView", "AbsAddBillet"} ans = POST_JSON("/role/Test_Y/delete", headers=admin_h) assert ans["OK"] is True @@ -163,7 +163,7 @@ def test_modif_users_depts(api_admin_headers): ) role_chef = POST_JSON( "/role/create/chef", - {"permissions": ["ScoView", "ScoUsersAdmin", "ScoUsersView"]}, + {"permissions": ["ScoView", "UsersAdmin", "UsersView"]}, headers=admin_h, ) _ = POST_JSON( diff --git a/tests/ressources/samples/samples.csv b/tests/ressources/samples/samples.csv index 27354f57309cb0816d6225baec48c95a67555b21..3a4eb23ca6ff283c91e76bb0be20245297a7bc1e 100644 --- a/tests/ressources/samples/samples.csv +++ b/tests/ressources/samples/samples.csv @@ -91,11 +91,11 @@ "partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST"; "partition";"/partition/1";"ScoView";"GET"; "permissions";"/permissions";"ScoView";"GET"; -"role-add_permission";"/role/customRole/add_permission/ScoUsersView";"ScoSuperAdmin";"POST"; -"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""ScoUsersView""]}" +"role-add_permission";"/role/customRole/add_permission/UsersView";"ScoSuperAdmin";"POST"; +"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""UsersView""]}" "role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST"; "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"; "roles";"/roles";"ScoView";"GET"; "test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET"; diff --git a/tests/unit/test_users.py b/tests/unit/test_users.py index 8e08542478b11fb2b0902f32dda7b89690cf2b31..789ebc5ca943acb21ffefb7d4913e7aca99d9cc3 100644 --- a/tests/unit/test_users.py +++ b/tests/unit/test_users.py @@ -32,7 +32,7 @@ def test_password_hashing(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") assert not role.has_permission(perm) role.add_permission(perm) @@ -51,19 +51,19 @@ def test_roles_permissions(test_client): role = Role.query.filter_by(name="Ens").first() assert role assert role.has_permission(Permission.ScoView) - assert role.has_permission(Permission.ScoAbsChange) + assert role.has_permission(Permission.AbsChange) # Permissions de Admin role = Role.query.filter_by(name="Admin").first() - assert role.has_permission(Permission.ScoEtudChangeAdr) + assert role.has_permission(Permission.EtudChangeAdr) # Permissions de Secr role = Role.query.filter_by(name="Secr").first() - assert role.has_permission(Permission.ScoEtudChangeAdr) - assert not role.has_permission(Permission.ScoEditAllNotes) + assert role.has_permission(Permission.EtudChangeAdr) + assert not role.has_permission(Permission.EditAllNotes) def test_users_roles(test_client): dept = DEPT - perm = Permission.ScoAbsChange + perm = Permission.AbsChange perm2 = Permission.ScoView u = User(user_name="un_enseignant") db.session.add(u) diff --git a/tools/fakedatabase/create_test_api_database.py b/tools/fakedatabase/create_test_api_database.py index 7ee00b32a00534d2337e52a71385633ea6ca75c1..5c300770f6a48382b52bb3518889b47f89e5410b 100644 --- a/tools/fakedatabase/create_test_api_database.py +++ b/tools/fakedatabase/create_test_api_database.py @@ -86,25 +86,25 @@ def create_users(depts: list[Departement]) -> tuple: """Crée les roles et utilisateurs nécessaires aux tests""" dept = depts[0] # 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() if role_lecteur is None: print("Erreur: rôle LecteurAPI non existant") sys.exit(1) perm_sco_view = Permission.get_by_name("ScoView") 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) # Edition billets - perm_billets = Permission.get_by_name("ScoAbsAddBillet") + perm_billets = Permission.get_by_name("AbsAddBillet") 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) db.session.add(role_lecteur) # Un role pour juste voir les utilisateurs role_users_viewer = Role( - name="UsersViewer", permissions=Permission.ScoUsersView | Permission.ScoView + name="UsersViewer", permissions=Permission.UsersView | Permission.ScoView ) db.session.add(role_users_viewer) # Role View sur l'API, pour demander un jeton