API: /etudiants/courants avec restriction aux départements

This commit is contained in:
Emmanuel Viennet 2022-07-24 15:51:13 +02:00
parent 0535d99456
commit 936fe3d716
4 changed files with 83 additions and 18 deletions

View File

@ -28,6 +28,7 @@ from functools import wraps
from flask import g
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
import flask_login
from flask_login import current_user
from app import log
@ -61,6 +62,7 @@ def verify_token(token) -> User:
"""
user = User.check_token(token) if token else None
flask_login.login_user(user)
g.current_user = user
return user

View File

@ -8,7 +8,9 @@
API : accès aux étudiants
"""
from flask import jsonify
from flask import g, jsonify
from flask_login import current_user
from sqlalchemy import or_
import app
from app.api import bp
@ -27,33 +29,68 @@ from app.scodoc.sco_permissions import Permission
@permission_required_api(Permission.ScoView, Permission.APIView)
def etudiants_courants(long=False):
"""
Liste des étudiants inscrits dans un formsemestre actuellement en cours.
La liste des étudiants des semestres "courants" (tous département)
(date du jour comprise dans la période couverte par le sem.)
dans lesquels l'utilisateur a le rôle APIView (donc tous si le dept du
rôle est None).
Exemple de résultat :
[
{
"id": 1,
"nip": 1,
"nom": "MOREL",
"prenom": "JACQUES",
"civilite": "X",
},
{
"id": 2,
"nip": 2,
"nom": "GILLES",
"prenom": "MAXIME",
"civilite": "X",
},
{
"id": 1234,
"nip": "12345678",
"ine": null,
"nom": "JOHN",
"nom_usuel": None,
"prenom": "DEUF",
"civilite": "M",
}
...
]
En format "long":
{
"boursier": True,
"civilite": "F",
"code_ine": "AP987654",
"code_nip": "1234567",
"codepostaldomicile": "92800",
"date_naissance": "21/06/2000",
"dept_acronym": "CJ",
"dept_id": 1,
"dept_naissance": "092",
"description": "infos portail",
"domicile": "Plaza Condell",
"email": "jeanne.dupont@xxx.fr",
"emailperso": "",
"etudid": 4853,
"id": 4863,
"lieu_naissance": "SEVRES",
"nationalite": "",
"nom": "DUPONT",
"nomprenom": "Mme Jeanne Dupont",
"paysdomicile": "FRANCE",
"prenom": "JEANNE",
"telephone": "0102030405",
"telephonemobile": "",
"typeadresse": "domicile",
"villedomicile": "VALPARAISO",
}
"""
allowed_depts = current_user.get_depts_with_permission(
Permission.APIView | Permission.ScoView
)
etuds = Identite.query.filter(
Identite.id == FormSemestreInscription.etudid,
FormSemestreInscription.formsemestre_id == FormSemestre.id,
FormSemestre.date_debut <= app.db.func.now(),
FormSemestre.date_fin >= app.db.func.now(),
)
if not None in allowed_depts:
# restreint aux départements autorisés:
etuds = etuds.join(Departement).filter(
or_(Departement.acronym == acronym for acronym in allowed_depts)
)
if long:
data = [etud.to_dict_bul(include_urls=False) for etud in etuds]
else:

View File

@ -315,6 +315,20 @@ class User(UserMixin, db.Model):
if r is not None
)
def get_depts_with_permission(self, permission: int) -> list[str]:
"""Liste des acronymes de département dans lesquels cet utilisateur
possède la permission indiquée.
L'"acronyme" None signifie "tous les départements".
Si plusieurs permissions (plusieurs bits) sont indiquées, c'est un "ou":
les départements dans lesquels l'utilisateur a l'une des permissions.
"""
return [
user_role.dept
for user_role in UserRole.query.filter_by(user=self)
.join(Role)
.filter(Role.permissions.op("&")(permission) != 0)
]
def is_administrator(self):
"True if i'm an active SuperAdmin"
return self.active and self.has_permission(Permission.ScoSuperAdmin, dept=None)

View File

@ -276,6 +276,7 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e
if perm_to_add or perm_to_remove:
db.session.add(role)
db.session.commit()
print(role)
@app.cli.command()
@ -301,16 +302,27 @@ def user_role(username, dept_acronym=None, add_role_name=None, remove_role_name=
if not user:
sys.stderr.write(f"user_role: user {username} does not exists\n")
return 1
# Sans argument, affiche les rôles de l'utilisateur
if dept_acronym is None and add_role_name is None and remove_role_name is None:
print(f"Roles for user {user.user_name}")
for user_role in sorted(
user.user_roles, key=lambda ur: (ur.dept or "", ur.role.name)
):
print(f"""{user_role.dept or "tous"}:\t{user_role.role.name}""")
if dept_acronym:
dept = models.Departement.query.filter_by(acronym=dept_acronym).first()
if dept is None:
sys.stderr.write(f"Erreur: le departement {dept} n'existe pas !\n")
sys.stderr.write(f"Erreur: le departement {dept_acronym} n'existe pas !\n")
return 2
if add_role_name:
role = Role.query.filter_by(name=add_role_name).first()
if role is None:
sys.stderr.write(f"user_role: role {add_role_name} does not exists\n")
sys.stderr.write(
f"""user_role: role {add_role_name} does not exists
(use list-roles to display existing roles)\n"""
)
return 2
user.add_role(role, dept_acronym)
if remove_role_name: