From cf95abbf17316296d52fb35cc26a884b9179bfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20ARNAUDEAU?= Date: Fri, 31 Mar 2017 12:35:29 +0200 Subject: [PATCH] =?UTF-8?q?TG-36=20:=20LivretAPI=20->=20cr=C3=A9ation=20de?= =?UTF-8?q?=20livret=20+=20s=C3=A9curisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/OLA.mysql | 3 ++ backend/app/OLA_DATA.mysql | 18 ------- backend/app/api/GroupAPI.py | 26 +++++---- backend/app/api/LivretAPI.py | 98 ++++++++++++++++++---------------- backend/app/api/UserAPI.py | 24 ++++++--- backend/app/api/UserInfoAPI.py | 4 +- backend/app/api/mailsModels.py | 19 ++++++- 7 files changed, 104 insertions(+), 88 deletions(-) delete mode 100644 backend/app/OLA_DATA.mysql diff --git a/backend/OLA.mysql b/backend/OLA.mysql index 79529a8..80d8b2c 100644 --- a/backend/OLA.mysql +++ b/backend/OLA.mysql @@ -66,6 +66,7 @@ CREATE TABLE IF NOT EXISTS LIVRET contract_type INT NOT NULL, contract_start DATE NOT NULL, contract_end DATE NOT NULL, + description TEXT NOT NULL, ressources_dir VARCHAR(512), opened TINYINT(1) NOT NULL, expire DATE NOT NULL, @@ -143,3 +144,5 @@ CREATE UNIQUE INDEX user_email ON `USER` (`email`); CREATE UNIQUE INDEX user_hash ON `USER` (`hash`); +CREATE UNIQUE INDEX tutorship_unique_bygroup + ON `TUTORSHIP` (`group_id`, `student_id`); diff --git a/backend/app/OLA_DATA.mysql b/backend/app/OLA_DATA.mysql deleted file mode 100644 index 1daf4d5..0000000 --- a/backend/app/OLA_DATA.mysql +++ /dev/null @@ -1,18 +0,0 @@ -USE OLA; -INSERT INTO SETTINGS VALUES ('URL_BASE_DIRECTORY', '/OLA_RESSOURCES/', 'Répertoire base pour le dépot des fichiers'); -INSERT INTO SETTINGS VALUES ('OLA_URL', 'ola.univ-tlse2.fr/', 'URL de l application'); - -INSERT INTO `USER` VALUES (1, 'sec', '1', 'sec@univ-tlse2.fr', '01.23.45.67.89'); -INSERT INTO `USER` VALUES (2, 'etu1', '4', 'etu1@univ-tlse2.fr', '01.23.45.67.89'); -INSERT INTO `USER` VALUES (3, 'etu2', '4', 'etu2@univ-tlse2.fr', '01.23.45.67.89'); -INSERT INTO `USER` VALUES (4, 'etu3', '4', 'etu3@univ-tlse2.fr', '01.23.45.67.89'); -INSERT INTO `USER` VALUES (5, 'resp', '2-3', 'resp@univ-tlse2.fr', '01.23.45.67.89'); -INSERT INTO `USER` VALUES (6, 'tut', '3', 'tut@univ-tlse2.fr', '01.23.45.67.89'); - -INSERT INTO `GROUP` VALUES (1, 'M2_ICE_2016-2017_TEST', '2017', 'Master2 ICE', 'Master 2 Informatique Collaborative en Entreprise', 'Sciences du chômage proffessionnel', 5, 1, '/home/dan/PycharmProjects/OLA/backend/app/OLA_RESSOURCES/M2_ICE_2016-2017_TEST'); -INSERT INTO `GROUP` VALUES (2, 'M1_ICE_2016-2017_TEST', '2017', 'Master1 ICE', 'Master 1 Informatique Collaborative en Entreprise', 'Sciences du chômage proffessionnel', 5, 1, '/home/dan/PycharmProjects/OLA/backend/app/OLA_RESSOURCES/M1_ICE_2016-2017_TEST'); - -INSERT INTO TUTORSHIP VALUES (DEFAULT, 1, 2, 5); -INSERT INTO TUTORSHIP VALUES (DEFAULT, 2, 4, 5); -INSERT INTO TUTORSHIP VALUES (DEFAULT, 1, 3, 6); - diff --git a/backend/app/api/GroupAPI.py b/backend/app/api/GroupAPI.py index deaa810..781b566 100644 --- a/backend/app/api/GroupAPI.py +++ b/backend/app/api/GroupAPI.py @@ -12,6 +12,7 @@ class GroupAPI(Resource): """ Group Api Resource """ + @login_required(roles=[Roles.resp_formation]) def post(self): args = request.get_json(cache=False, force=True) @@ -48,8 +49,8 @@ class GroupAPI(Resource): "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) - if "2" not in user['role'].split('-'): - role = user['role'] + "-2" + if str(Roles.resp_formation) not in user['role'].split('-'): + role = user['role'] + "-" + str(Roles.resp_formation) query = USER.update().values(role=role).where(USER.c.id == resp_id) query.execute() @@ -69,8 +70,8 @@ class GroupAPI(Resource): "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) - if "1" not in user['role'].split('-'): - role = user['role'] + "-1" + if str(Roles.secretaire) not in user['role'].split('-'): + role = user['role'] + "-" + str(Roles.secretaire) query = USER.update().values(role=role).where(USER.c.id == sec_id) query.execute() @@ -86,6 +87,7 @@ class GroupAPI(Resource): return {"GID": res.lastrowid}, 201 + @login_required(roles=Roles.resp_formation) def put(self, gid): args = request.get_json(cache=False, force=True) if not checkParams(['name', 'year', 'class_short', 'class_long', 'department', 'resp_id', 'sec_id'], args): @@ -125,8 +127,8 @@ class GroupAPI(Resource): "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) - if "2" not in user['role'].split('-'): - role = user['role'] + "-2" + if str(Roles.resp_formation) not in user['role'].split('-'): + role = user['role'] + "-" + str(Roles.resp_formation) query = USER.update().values(role=role).where(USER.c.id == resp_id) query.execute() @@ -146,8 +148,8 @@ class GroupAPI(Resource): "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) - if "1" not in user['role'].split('-'): - role = user['role'] + "-1" + if str(Roles.secretaire) not in user['role'].split('-'): + role = user['role'] + "-" + str(Roles.secretaire) query = USER.update().values(role=role).where(USER.c.id == sec_id) query.execute() @@ -166,12 +168,14 @@ class GroupAPI(Resource): return {"GID": gid}, 200 + @login_required() def get(self, gid=0, name=""): if gid > 0: return {'GROUP': getGroup(gid=gid)}, 200 elif name != "": return {'GROUP': getGroup(name=name)}, 200 + @login_required(roles=Roles.resp_formation) def options(self, gid): args = request.get_json(cache=False, force=True) if not checkParams(['pairs'], args): @@ -188,16 +192,16 @@ class GroupAPI(Resource): stud = getUser(uid=p[0]) if stud is None: return {"ERROR": "The user with id " + str(p[0]) + " does not exists !"}, 400 - elif stud['role'] != "4": + elif stud['role'] != str(Roles.etudiant): return {"ERROR": "A student must have the 'student' role !"}, 400 tutor = getUser(uid=p[1]) if tutor is None: return {"ERROR": "The user with id " + str(p[1]) + " does not exists !"}, 400 - elif tutor['role'] == "4": + elif tutor['role'] == str(Roles.etudiant): return {"ERROR": "A student can't be a tutor !"}, 400 elif "3" not in tutor['role'].split('-'): - role = tutor['role'] + "-3" + role = tutor['role'] + "-" + str(Roles.tuteur_univ) query = USER.update().values(role=role).where(USER.c.id == p[1]) query.execute() except IndexError: diff --git a/backend/app/api/LivretAPI.py b/backend/app/api/LivretAPI.py index 0667f1c..596a054 100644 --- a/backend/app/api/LivretAPI.py +++ b/backend/app/api/LivretAPI.py @@ -1,80 +1,83 @@ import os +from datetime import datetime +from dateutil.relativedelta import relativedelta +from flask import session from flask_restful import Resource, request +from sqlalchemy import and_ from app.api import mailsModels -from app.model import Roles, getParam, getGroup, getUser, USER, GROUP, TUTORSHIP -from app.utils import send_mail, checkParams from app.api.LoginAPI import login_required +from app.model import Roles, getParam, getGroup, getUser, USER, GROUP, TUTORSHIP, LIVRET +from app.utils import send_mail, checkParams + class LivretAPI(Resource): """ Livret Api Resource """ + @login_required(roles=[Roles.etudiant]) def post(self): args = request.get_json(cache=False, force=True) - if not checkParams(['name', 'year', 'class_short', 'class_long', 'department', 'resp_id', 'sec_id'], args): + if not checkParams(['student_id', 'group_id', 'etutor_id', 'company_name', 'company_address', 'contract_type', + 'contract_start', 'contract_end', 'description'], args): return {"ERROR": "One or more parameters are missing !"}, 400 - name = args['name'] - year = args['year'] - class_short = args['class_short'] - class_long = args['class_long'] - department = args['department'] - resp_id = args['resp_id'] - sec_id = args['sec_id'] - res_dir = getParam('BASE_DIRECTORY') + name + "/" + user = session.get("user") + group_id = args['group_id'] + etutor_id = args['etutor_id'] + company_name = args['company_name'] + company_address = args['company_address'] + contract_type = int(args['contract_type']) + contract_start = datetime.strptime(args['contract_start'], "%d-%m-%Y") + contract_end = datetime.strptime(args['contract_end'], "%d-%m-%Y") + description = args['description'] mails = [] - group = getGroup(name=name) - if group is not None: - return {"GID": group["id"]}, 200 + group = getGroup(gid=group_id) + if group is None: + return {"ERROR": "This group does not exists !"}, 405 - user = getUser(uid=resp_id) + query = TUTORSHIP.select(and_(TUTORSHIP.c.group_id == group_id, TUTORSHIP.c.student_id == user["id"])) + res = query.execute() + tutorship = res.first() + + if tutorship is None: + return {"ERROR": "This student is not in this group !"}, 405 + + tutorship_id = tutorship.id + + user = getUser(uid=etutor_id) if user is None: - return {"ERROR": "The user with id " + str(resp_id) + " does not exists !"}, 400 + return {"ERROR": "The user with id " + str(etutor_id) + " does not exists !"}, 400 else: query = USER.select(USER.c.id == user["id"]) rows = query.execute() res = rows.first() if res.hash is not None and len(res.hash) > 0: - mail = mailsModels.getMailContent("NEW_RESP_OF_GROUP", {"GROUP": name, - "URL": getParam('OLA_URL') + "registration/" - + res.hash}) - else: - mail = mailsModels.getMailContent("RESP_OF_GROUP", {"GROUP": name, - "URL": getParam('OLA_URL')}) - - mails.append((user["email"], mail)) - if "2" not in user['role'].split('-'): - role = user['role'] + "-2" - query = USER.update().values(role=role).where(USER.c.id == resp_id) - query.execute() - - user = getUser(uid=sec_id) - if user is None: - return {"ERROR": "The user with id " + str(sec_id) + " does not exists !"}, 400 - else: - query = USER.select(USER.c.id == user["id"]) - rows = query.execute() - res = rows.first() - if res.hash is not None and len(res.hash) > 0: - mail = mailsModels.getMailContent("NEW_SEC_OF_GROUP", {"GROUP": name, + mail = mailsModels.getMailContent("NEW_ETUTOR_ADDED", {"GROUP": group["name"], "URL": getParam('OLA_URL') + "registration/" + res.hash}) else: - mail = mailsModels.getMailContent("SEC_OF_GROUP", {"GROUP": name, + mail = mailsModels.getMailContent("ETUTOR_ADDED", {"GROUP": group["name"], "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) - if "1" not in user['role'].split('-'): - role = user['role'] + "-1" - query = USER.update().values(role=role).where(USER.c.id == sec_id) - query.execute() + if str(Roles.tuteur_entreprise) not in user['role'].split('-'): + return {"ERROR": "The user with id " + str(etutor_id) + + " doesn't have the 'etutor' role (" + str(Roles.tuteur_entreprise) + ") !"}, 400 - query = GROUP.insert().values(name=name, year=year, class_short=class_short, class_long=class_long, - department=department, resp_id=resp_id, sec_id=sec_id, ressources_dir=res_dir) + if contract_start > contract_end: + return {"ERROR": "The contract start can't be after its end !"}, 400 + + res_dir = group["ressources_dir"] + user['id'] + "/" + expire = datetime.now() + relativedelta(year=1) + + query = LIVRET.insert().values(tutorship_id=tutorship_id, etutor_id=etutor_id, company_name=company_name, + company_address=company_address, contract_type=contract_type, + contract_start=contract_start, contract_end=contract_end, + description=description, ressources_dir=res_dir, opened='1', expire=expire) res = query.execute() os.mkdir(res_dir) @@ -83,8 +86,9 @@ class LivretAPI(Resource): mail = m[1] send_mail(mail[0], addr, mail[1]) - return {"GID": res.lastrowid}, 201 + return {"LID": res.lastrowid}, 201 + @login_required(roles=[Roles.etudiant]) def put(self, gid): args = request.get_json(cache=False, force=True) if not checkParams(['name', 'year', 'class_short', 'class_long', 'department', 'resp_id', 'sec_id'], args): @@ -165,12 +169,14 @@ class LivretAPI(Resource): return {"GID": gid}, 200 + @login_required() def get(self, gid=0, name=""): if gid > 0: return {'GROUP': getGroup(gid=gid)}, 200 elif name != "": return {'GROUP': getGroup(name=name)}, 200 + @login_required(roles=Roles.etudiant) def options(self, gid): args = request.get_json(cache=False, force=True) if not checkParams(['pairs'], args): diff --git a/backend/app/api/UserAPI.py b/backend/app/api/UserAPI.py index 5b61425..3c2194d 100644 --- a/backend/app/api/UserAPI.py +++ b/backend/app/api/UserAPI.py @@ -1,10 +1,11 @@ from hashlib import sha256 +from flask import session from flask_restful import Resource, request +from app.api.LoginAPI import login_required from app.model import Roles, getUser, hashExists, USER from app.utils import checkParams, get_random_string -from app.api.LoginAPI import login_required class UserAPI(Resource): """ @@ -52,9 +53,14 @@ class UserAPI(Resource): password = sha256(psw.encode('utf-8')).hexdigest() - if getUser(uid=uid) is None: + user = getUser(uid=uid) + if user is None: return {"ERROR": "This user doesn't exists !"}, 405 + # On n'autorise pas de modifcation anonyme d'un profil s'il est déjà activé (si il a un mdp) + if user["password"] is not None and user["password"] != "" and session.get("user", None) is None: + return {"msg": "UNAUTHORIZED"}, 401 + if getUser(email=email) is not None: return {"ERROR": "A user with this email already exists !"}, 405 @@ -64,9 +70,11 @@ class UserAPI(Resource): return {"UID": uid}, 200 def get(self, uid=0, email="", hashcode=""): - if uid > 0: - return {'USER': getUser(uid=uid)}, 200 - elif email != "": - return {'USER': getUser(email=email)}, 200 - elif hashcode != "": - return {'USER': getUser(hashcode=hashcode)}, 200 + if session.get('user', None) is not None: + if uid > 0: + return {'USER': getUser(uid=uid)}, 200 + elif email != "": + return {'USER': getUser(email=email)}, 200 + + if hashcode != "": + return {'USER': getUser(hashcode=hashcode)}, 200 \ No newline at end of file diff --git a/backend/app/api/UserInfoAPI.py b/backend/app/api/UserInfoAPI.py index 5e2f6cc..eb46881 100644 --- a/backend/app/api/UserInfoAPI.py +++ b/backend/app/api/UserInfoAPI.py @@ -1,6 +1,6 @@ from flask import session from flask_restful import Resource -from app.api.LoginAPI import login_required + from app.model import LIVRET, TUTORSHIP, and_ @@ -9,7 +9,6 @@ class UserInfoAPI(Resource): UserInfo Api Resource """ - @login_required() def get(self): user = session.get("user", None) return {'USER': user}, 200 @@ -19,7 +18,6 @@ class UserGroupsAPI(Resource): """ UserGroups Api Resource """ - @login_required() def get(self): user = session.get("user", None) if user is not None: diff --git a/backend/app/api/mailsModels.py b/backend/app/api/mailsModels.py index e928d94..b92ee26 100644 --- a/backend/app/api/mailsModels.py +++ b/backend/app/api/mailsModels.py @@ -11,7 +11,7 @@ _STUD_OF_GROUP = ( _NEW_RESP_OF_GROUP = ("Votre compte OLA a été créé !", "Bonjour,

Votre compte vient d'être créé dans l'Outil du " "Livret de l'Alternant en tant que responsable du groupe #GROUPE. Vous pouvez dès " - "maintenant l'activer, en vous rendant à l'adresse :
" + "maintenant l'activer en vous rendant à l'adresse :
" "#URL

Bonne journée !

") _RESP_OF_GROUP = ( @@ -22,7 +22,7 @@ _RESP_OF_GROUP = ( _NEW_SEC_OF_GROUP = ("Votre compte OLA a été créé !", "Bonjour,

Votre compte vient d'être créé dans l'Outil du " "Livret de l'Alternant en tant que secrétaire du groupe #GROUPE. Vous pouvez dès " - "maintenant l'activer, en vous rendant à l'adresse :
" + "maintenant l'activer en vous rendant à l'adresse :
" "#URL

Bonne journée !

") _SEC_OF_GROUP = ( @@ -31,6 +31,17 @@ _SEC_OF_GROUP = ( "maintenant y accéder en vous rendant à l'adresse :
" "#URL

Bonne journée !

") +_NEW_ETUTOR_ADDED = ("Votre compte OLA a été créé !", "Bonjour,

Votre compte vient d'être créé dans l'Outil du " + "Livret de l'Alternant de l'Université Toulouse Jean-Jaurès en tant que tuteur dans le groupe #GROUPE. Vous pouvez dès " + "maintenant l'activer en vous rendant à l'adresse :
" + "#URL

Bonne journée !

") + +_ETUTOR_ADDED = ( + "Vous avez été déclaré comme tuteur dans OLA !", "Bonjour,

Votre compte vient d'être ajouté dans l'Outil du " + "Livret de l'Alternant de l'Université Toulouse Jean-Jaurès en tant que tuteur dans le groupe #GROUPE. Vous pouvez dès " + "maintenant accéder à votre compte en vous rendant à l'adresse :
" + "#URL

Bonne journée !

") + def getMailContent(mail_type, args): if mail_type == "NEW_STUD_OF_GROUP": @@ -45,6 +56,10 @@ def getMailContent(mail_type, args): mail = _NEW_SEC_OF_GROUP elif mail_type == "SEC_OF_GROUP": mail = _SEC_OF_GROUP + elif mail_type == "NEW_ETUTOR_ADDED": + mail = _NEW_ETUTOR_ADDED + elif mail_type == "ETUTOR_ADDED": + mail = _ETUTOR_ADDED else: raise Exception("Unknown mail type !")