TG-40 : PeriodAPI + Sécurisation

This commit is contained in:
Clément ARNAUDEAU 2017-05-08 19:51:28 +02:00
parent 5641f8ebd9
commit 335bd04803
7 changed files with 215 additions and 6 deletions

View File

@ -0,0 +1,31 @@
from flask import session
from flask_restful import Resource
from app.api.LoginAPI import login_required
from app.model import getLivret, PERIOD, getPeriod
class GetAllAPI(Resource):
"""
GetAll Api Resource
Renvoie toutes les occurences correspondant à un critère
"""
@login_required()
def get(self, what, value):
user = session.get("user")
result = []
if what == "periodsOfLivret": # Toutes les périodes associées à un livret
if value > 0:
livret = getLivret(lid=value)
if livret is None:
return {"ERROR": "This livret doesn't exists !"}, 405
query = PERIOD.select(PERIOD.c.livret_id == value)
res = query.execute()
for row in res:
result.append(getPeriod(pid=row.id))
else:
return {'ERROR': 'Unkown parameter :' + str(what)}, 200
return {'RESULT': result}, 200

View File

@ -48,11 +48,15 @@ class LivretAPI(Resource):
if livret is not None:
return {"LID": livret["id"]}, 200
user = getUser(uid=etutor_id)
if user is None:
# On vérifie que l'utilisateur actuel a le droit de modifier ce livret
if user["id"] != livret["tutorship_id"]["student_id"]:
return {"ERROR": "UNAUTHORIZED"}, 401
user2 = getUser(uid=etutor_id)
if user2 is None:
return {"ERROR": "The user with id " + str(etutor_id) + " does not exists !"}, 400
else:
query = USER.select(USER.c.id == user["id"])
query = USER.select(USER.c.id == user2["id"])
rows = query.execute()
res = rows.first()
if res.hash is not None and len(res.hash) > 0:
@ -63,8 +67,8 @@ class LivretAPI(Resource):
mail = mailsModels.getMailContent("ETUTOR_ADDED", {"GROUPE": group["name"],
"URL": getParam('OLA_URL')})
mails.append((user["email"], mail))
if str(Roles.tuteur_entreprise) not in user['role'].split('-'):
mails.append((user2["email"], mail))
if str(Roles.tuteur_entreprise) not in user2['role'].split('-'):
return {"ERROR": "The user with id " + str(etutor_id) +
" doesn't have the 'etutor' role (" + str(Roles.tuteur_entreprise) + ") !"}, 400
@ -108,6 +112,11 @@ class LivretAPI(Resource):
if livret is None:
return {"ERROR": "This livret does not exists !"}, 405
# On vérifie que l'utilisateur actuel a le droit de modifier ce livret
user = session.get("user")
if user["id"] != livret["tutorship_id"]["student_id"]:
return {"ERROR": "UNAUTHORIZED"}, 401
user = getUser(uid=etutor_id)
if user is None:
return {"ERROR": "The user with id " + str(etutor_id) + " does not exists !"}, 400

View File

@ -0,0 +1,116 @@
import os
from datetime import datetime
from flask import session
from flask_restful import Resource, request
from sqlalchemy import select, and_
from app.api import mailsModels
from app.api.LoginAPI import login_required
from app.model import Roles, getParam, getGroup, getUser, LIVRET, getLivret, TUTORSHIP, PERIOD, getPeriod, \
TypesPeriode
from app.utils import send_mail, checkParams, get_random_string
class PeriodAPI(Resource):
"""
Period Api Resource
"""
@login_required(roles=[Roles.resp_formation])
def post(self):
args = request.get_json(cache=False, force=True)
if not checkParams(['group_id', 'period_type', 'start', 'end'], args):
return {"ERROR": "One or more parameters are missing !"}, 400
group_id = args['group_id']
period_type = args['period_type']
start = datetime.strptime(args['start'], "%d-%m-%Y")
end = datetime.strptime(args['end'], "%d-%m-%Y")
# On vérifie que le groupe existe
group = getGroup(gid=group_id)
if group is None:
return {"ERROR": "This group with id " + str(group_id) + "does not exists !"}, 405
if start > end:
return {"ERROR": "The period's start can't be after its end !"}, 400
# On vérifie que l'utilisateur actuel a le droit de modifier ce groupe
user = session.get("user")
if user["id"] != group["resp_id"]:
return {"ERROR": "UNAUTHORIZED"}, 401
# On récupère tous les livrets de ce groupe
query = select([LIVRET.c.id, TUTORSHIP.c.student_id]).where(
and_(TUTORSHIP.c.id == LIVRET.c.tutorship_id, TUTORSHIP.c.group_id == group_id))
res = query.execute()
# Pour chaque livret du groupe on ajoute la période et on prévient l'étudiant
for row in res:
# On crée un répertoire avec un nom aléatoire
res_dir = group["ressources_dir"] + "/" + str(row.student_id) + "/" + get_random_string() + "/"
while os.path.exists(res_dir):
res_dir = group["ressources_dir"] + "/" + str(row.student_id) + "/" + get_random_string() + "/"
# Enregistrement des infos en base
query = PERIOD.insert().values(livret_id=row.id, type=period_type, start=start, end=end,
ressources_dir=res_dir)
query.execute()
os.mkdir(res_dir)
# Envoi d'un mail
mail = mailsModels.getMailContent("NEW_PERIOD", {"GROUPE": group["name"],
"URL": getParam('OLA_URL') + "mon_livret"})
send_mail(mail[0], getUser(row.student_id)["email"], mail[1])
return {"RESULT": "OK"}, 201
@login_required(roles=[Roles.etudiant, Roles.tuteur_entreprise])
def put(self, pid):
args = request.get_json(cache=False, force=True)
if not checkParams(['text'], args):
return {"ERROR": "One or more parameters are missing !"}, 400
text = args['text']
user = session.get("user")
mails = []
# On vérifie que la période existe
period = getPeriod(pid)
if period is None:
return {"ERROR": "This period does not exists !"}, 405
# On vérifie que l'utilisateur actuel a le droit de modifier ce livret (étudiant ou tuteur)
livret = getLivret(lid=period["livret_id"])
if user["id"] != livret["etutor_id"]["id"] and user["id"] != livret["tutorship_id"]["student_id"]["id"]:
return {"ERROR": "UNAUTHORIZED"}, 401
# Si c'est le commentaire de l'étudiant, on prévient le tuteur
if user["role"] == str(Roles.etudiant):
mail = mailsModels.getMailContent("STUD_COMMENT_ADDED", {"ETUDIANT": user["name"],
"URL": getParam('OLA_URL')})
mails.append((user["email"], mail))
query = PERIOD.update().values(student_desc=text).where(PERIOD.c.id == pid)
else: # Sinon on vérifie que c'est une période d'entreprise
if period["type"] == TypesPeriode.universitaire:
return {"ERROR": "A tutor can't modify a university period !"}
mail = mailsModels.getMailContent("ETUTOR_COMMENT_ADDED", {"TUTEUR": user["name"],
"URL": getParam('OLA_URL')})
mails.append((user["email"], mail))
query = PERIOD.update().values(etutor_desc=text).where(PERIOD.c.id == pid)
query.execute()
for m in mails:
addr = m[0]
mail = m[1]
send_mail(mail[0], addr, mail[1])
return {"PID": pid}, 200
@login_required()
def get(self, pid):
if pid > 0:
return {'PERIOD': getPeriod(pid=pid)}, 200

View File

@ -42,6 +42,25 @@ _ETUTOR_ADDED = (
"maintenant accéder à votre compte en vous rendant à l'adresse : <br/>"
"<a href='#URL'>#URL</a></p><p>Bonne journée !</p>")
_NEW_PERIOD = (
"Nouvelle période ouverte dans OLA !", "Bonjour,<br/><p>Une nouvelle période vient d'être crée sur l'Outil du "
"Livret de l'Alternant dans le groupe <b>#GROUPE</b>. Vous pouvez dès "
"maintenant entrer vos commentaires en vous rendant à l'adresse : <br/>"
"<a href='#URL'>#URL</a></p><p>Bonne journée !</p>")
_STUD_COMMENT_ADDED = (
"Livret de l'alternant mis à jour !", "Bonjour,<br/><p>#ETUDIANT vient de mettre à jour son livret sur l'Outil du "
"Livret de l'Alternant. Vous pouvez dès "
"maintenant entrer à votre tour vos commentaires en vous rendant à l'adresse : <br/>"
"<a href='#URL'>#URL</a></p><p>Bonne journée !</p>")
_ETUTOR_COMMENT_ADDED = (
"Livret de l'alternant mis à jour !", "Bonjour,<br/><p>#TUTEUR vient de mettre à jour son livret sur l'Outil du "
"Livret de l'Alternant. Vous pouvez visualiser ces modifcations"
" en vous rendant à l'adresse : <br/>"
"<a href='#URL'>#URL</a></p><p>Bonne journée !</p>")
def getMailContent(mail_type, args):
if mail_type == "NEW_STUD_OF_GROUP":
@ -60,8 +79,14 @@ def getMailContent(mail_type, args):
mail = _NEW_ETUTOR_ADDED
elif mail_type == "ETUTOR_ADDED":
mail = _ETUTOR_ADDED
elif mail_type == "NEW_PERIOD":
mail = _NEW_PERIOD
elif mail_type == "STUD_COMMENT_ADDED":
mail = _STUD_COMMENT_ADDED
elif mail_type == "ETUTOR_COMMENT_ADDED":
mail = _ETUTOR_COMMENT_ADDED
else:
raise Exception("Unknown mail type !")
raise Exception("Unknown mail type : " + str(mail_type))
obj = mail[0]
content = str(mail[1])

View File

@ -45,3 +45,9 @@ def after_login():
# import api resources
importlib.import_module("app.urls")
@app.teardown_request
def shutdown_session(exception=None):
engine.dispose()
db.session.remove()

View File

@ -130,6 +130,19 @@ def getLivret(lid=0, group_id=0, student_id=0):
return None
def getPeriod(pid):
query = PERIOD.select(PERIOD.c.id == pid)
rows = query.execute()
res = rows.first()
if res is not None:
return {"id": res.id, "livret_id": res.livret_id, "type": res.type, "start": res.start.strftime('%d-%m-%Y'),
"end": res.end.strftime('%d-%m-%Y'), "student_desc": res.student_desc, "etutor_desc": res.etutor_desc,
"ressources_dir": res.ressources_dir}
else:
return None
def hashExists(test):
query = USER.select(USER.c.hash == test)
rows = query.execute()
@ -143,3 +156,8 @@ class Roles:
tuteur_univ = 3
etudiant = 4
tuteur_entreprise = 5
class TypesPeriode:
universitaire = 1
entreprise = 2

View File

@ -1,6 +1,8 @@
from app.api.GetAllAPI import GetAllAPI
from app.api.GroupAPI import GroupAPI
from app.api.LivretAPI import LivretAPI
from app.api.LoginAPI import LoginAPI
from app.api.PeriodAPI import PeriodAPI
from app.api.UserAPI import UserAPI
from app.api.UserInfoAPI import UserInfoAPI, UserGroupsAPI
from app.api.exampleapi import SomeApi
@ -16,3 +18,5 @@ api.add_resource(UserAPI, '/api/user', '/api/user/byuid/<int:uid>', '/api/user/b
api.add_resource(GroupAPI, '/api/group', '/api/group/bygid/<int:gid>', '/api/group/byname/<string:name>')
api.add_resource(LivretAPI, '/api/livret', '/api/livret/bylid/<int:lid>',
'/api/livret/bytutorship/<int:group_id>/<int:student_id>')
api.add_resource(PeriodAPI, '/api/period', '/api/period/bypid/<int:pid>')
api.add_resource(GetAllAPI, '/api/getAll/<string:what>/<int:value>')