From 0891214b30a06a52744420c941e9d7bdfce697a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20ARNAUDEAU?= Date: Sat, 6 May 2017 18:03:15 +0200 Subject: [PATCH] TG-40 : LivretAPI -> finalisation de l'API des livrets + correctifs --- API_Interfaces.txt | 3 +- backend/OLA_DATA.mysql | 2 +- backend/app/api/LivretAPI.py | 173 ++++++++++----------------------- backend/app/api/LoginAPI.py | 7 +- backend/app/api/UserAPI.py | 4 +- backend/app/api/mailsModels.py | 6 +- backend/app/model.py | 60 ++++++++++-- backend/app/urls.py | 3 +- 8 files changed, 117 insertions(+), 141 deletions(-) diff --git a/API_Interfaces.txt b/API_Interfaces.txt index 9a73149..745aba2 100644 --- a/API_Interfaces.txt +++ b/API_Interfaces.txt @@ -1,7 +1,7 @@ ####################### LoginAPI (api/login) ####################### -GET -> Authentication method +POST -> Authentication method Out: 200 -> AUTH_RESULT = "OK" : Authentication sucessful 401 -> AUTH_RESULT = "AUTHENTICATION_FAILURE" : Wrong login/password @@ -27,6 +27,7 @@ POST -> Create a user if it not already exists In: email = Email and login of the user (must be unique) role = Role of the user (can be concatenated with -) 1=secrétaire, 2=resp_formation, 3=tuteur_univ, 4=étudiant, 5=tuteur_ent + name = Display name of the user Out: 200 -> UID = : The user already exists with the id USER_ID 201 -> UID = : The user has been successfully created with the id USER_ID diff --git a/backend/OLA_DATA.mysql b/backend/OLA_DATA.mysql index 7c8db3a..ed16388 100644 --- a/backend/OLA_DATA.mysql +++ b/backend/OLA_DATA.mysql @@ -1,7 +1,7 @@ USE OLA; INSERT INTO SETTINGS VALUES ('BASE_DIRECTORY', '/OLA_RESSOURCES/', 'Répertoire base pour le dépot des fichiers'); INSERT INTO SETTINGS VALUES ('TEMPLATES_DIRECTORY', '/OLA_TEMPLATES/', '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 SETTINGS VALUES ('OLA_URL', 'http://ola.univ-tlse2.fr/', 'URL de l application'); INSERT INTO `USER` VALUES (1, '1', 'sec@univ-tlse2.fr', 'Secrétaire', DEFAULT, 'aZeRtYuIoP', '01.23.45.67.89'); INSERT INTO `USER` VALUES (2, '4', 'etu1@univ-tlse2.fr', 'Etudiant 1', DEFAULT, 'qSdFgHjKlM', '01.23.45.67.89'); diff --git a/backend/app/api/LivretAPI.py b/backend/app/api/LivretAPI.py index 596a054..0898901 100644 --- a/backend/app/api/LivretAPI.py +++ b/backend/app/api/LivretAPI.py @@ -1,14 +1,12 @@ import os -from datetime import datetime +from datetime import datetime, timedelta -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.api.LoginAPI import login_required -from app.model import Roles, getParam, getGroup, getUser, USER, GROUP, TUTORSHIP, LIVRET +from app.model import Roles, getParam, getGroup, getUser, USER, LIVRET, getLivret, getTutorship from app.utils import send_mail, checkParams @@ -20,7 +18,7 @@ class LivretAPI(Resource): @login_required(roles=[Roles.etudiant]) def post(self): args = request.get_json(cache=False, force=True) - if not checkParams(['student_id', 'group_id', 'etutor_id', 'company_name', 'company_address', 'contract_type', + if not checkParams(['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 @@ -39,14 +37,16 @@ class LivretAPI(Resource): if group is None: return {"ERROR": "This group does not exists !"}, 405 - query = TUTORSHIP.select(and_(TUTORSHIP.c.group_id == group_id, TUTORSHIP.c.student_id == user["id"])) - res = query.execute() - tutorship = res.first() + tutorship = getTutorship(gid=group_id, student=user["id"]) if tutorship is None: return {"ERROR": "This student is not in this group !"}, 405 - tutorship_id = tutorship.id + tutorship_id = tutorship["id"] + + livret = getLivret(group_id=group_id, student_id=user["id"]) + if livret is not None: + return {"ERROR": "This livret already exists !"}, 405 user = getUser(uid=etutor_id) if user is None: @@ -56,11 +56,11 @@ class LivretAPI(Resource): rows = query.execute() res = rows.first() if res.hash is not None and len(res.hash) > 0: - mail = mailsModels.getMailContent("NEW_ETUTOR_ADDED", {"GROUP": group["name"], + mail = mailsModels.getMailContent("NEW_ETUTOR_ADDED", {"GROUPE": group["name"], "URL": getParam('OLA_URL') + "registration/" + res.hash}) else: - mail = mailsModels.getMailContent("ETUTOR_ADDED", {"GROUP": group["name"], + mail = mailsModels.getMailContent("ETUTOR_ADDED", {"GROUPE": group["name"], "URL": getParam('OLA_URL')}) mails.append((user["email"], mail)) @@ -71,8 +71,8 @@ class LivretAPI(Resource): 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) + res_dir = group["ressources_dir"] + "/" + str(user['id']) + "/" + expire = datetime.now() + timedelta(days=365) query = LIVRET.insert().values(tutorship_id=tutorship_id, etutor_id=etutor_id, company_name=company_name, company_address=company_address, contract_type=contract_type, @@ -89,139 +89,66 @@ class LivretAPI(Resource): return {"LID": res.lastrowid}, 201 @login_required(roles=[Roles.etudiant]) - def put(self, gid): + def put(self, lid): 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(['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'].replace(" ", "_").replace("/", "-") - 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 + "/" + 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(gid=gid) - if group is None: - return {"ERROR": "This group does not exists !"}, 405 + livret = getLivret(lid=lid) + if livret is None: + return {"ERROR": "This livret does not exists !"}, 405 - group2 = getGroup(name=name) - if group2 is not None: - return {"ERROR": "A group with this name already exists !"}, 405 - - user = getUser(uid=resp_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": group["name"], - "URL": getParam('OLA_URL') + "registration/" - + res.hash}) + mail = mailsModels.getMailContent("NEW_ETUTOR_ADDED", + {"GROUPE": livret["tutorship_id"]["group_id"]["name"], + "URL": getParam('OLA_URL') + "registration/" + + res.hash}) else: - mail = mailsModels.getMailContent("RESP_OF_GROUP", {"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": group["name"], - "URL": getParam('OLA_URL') + "registration/" - + res.hash}) - else: - mail = mailsModels.getMailContent("SEC_OF_GROUP", {"GROUP": group["name"], + mail = mailsModels.getMailContent("ETUTOR_ADDED", {"GROUPE": livret["tutorship_id"]["group_id"]["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.update().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) \ - .where(GROUP.c.id == gid) + if contract_start > contract_end: + return {"ERROR": "The contract start can't be after its end !"}, 400 + + query = LIVRET.update().values(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) \ + .where(LIVRET.c.id == lid) query.execute() - if group["ressources_dir"] != res_dir: - os.rename(group["ressources_dir"], res_dir) - for m in mails: addr = m[0] mail = m[1] send_mail(mail[0], addr, mail[1]) - return {"GID": gid}, 200 + return {"LID": lid}, 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): - return {"ERROR": "One or more parameters are missing !"}, 400 - - pairs = args["pairs"] - - group = getGroup(gid=gid) - if group is None: - return {"ERROR": "This group does not exists !"}, 405 - - for p in pairs: - try: - 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": - 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": - return {"ERROR": "A student can't be a tutor !"}, 400 - elif "3" not in tutor['role'].split('-'): - role = tutor['role'] + "-3" - query = USER.update().values(role=role).where(USER.c.id == p[1]) - query.execute() - except IndexError: - return {"ERROR": "Pairs are incorrectly formed !"}, 409 - - query = TUTORSHIP.insert().values(group_id=gid, student_id=p[0], ptutor_id=p[1]) - query.execute() - - query = USER.select(USER.c.id == stud["id"]) - rows = query.execute() - res = rows.first() - if res.hash is not None and len(res.hash) > 0: - mail = mailsModels.getMailContent("NEW_STUD_OF_GROUP", {"GROUP": group["name"], - "URL": getParam('OLA_URL') + "registration/" - + res.hash}) - else: - mail = mailsModels.getMailContent("STUD_OF_GROUP", {"GROUP": group["name"], - "URL": getParam('OLA_URL')}) - - send_mail(mail[0], stud["email"], mail[1]) - - return {"RESULT": "Pairs added successfully"}, 200 + def get(self, lid=0, group_id=0, student_id=0): + if lid > 0: + return {'LIVRET': getLivret(lid=lid)}, 200 + elif group_id > 0 and student_id > 0: + return {'LIVRET': getLivret(group_id=group_id, student_id=student_id)}, 200 diff --git a/backend/app/api/LoginAPI.py b/backend/app/api/LoginAPI.py index b388529..e99686a 100644 --- a/backend/app/api/LoginAPI.py +++ b/backend/app/api/LoginAPI.py @@ -50,14 +50,13 @@ class LoginAPI(Resource): return {'AUTH_RESULT': 'OK'}, 200 - def login_required(roles=[]): def my_login_required(func): - def wrapper(*args): + def wrapper(*args, **kvargs): current_user = session.get('user', None) if current_user is None or (len(roles) != 0 and not sum([1 for x in current_user['role'].split("-") if int(x) in roles]) > 0): - return {"msg": "UNAUTHORIZED"}, 401 - return func(*args) + return {"ERROR": "UNAUTHORIZED"}, 401 + return func(*args, **kvargs) return wrapper return my_login_required diff --git a/backend/app/api/UserAPI.py b/backend/app/api/UserAPI.py index 3c2194d..9b14a41 100644 --- a/backend/app/api/UserAPI.py +++ b/backend/app/api/UserAPI.py @@ -7,11 +7,13 @@ from app.api.LoginAPI import login_required from app.model import Roles, getUser, hashExists, USER from app.utils import checkParams, get_random_string + class UserAPI(Resource): """ User Api Resource """ - @login_required(roles=[Roles.resp_formation]) + + @login_required(roles=[Roles.resp_formation, Roles.etudiant]) def post(self): args = request.get_json(cache=False, force=True) if not checkParams(['role', 'email', 'name'], args): diff --git a/backend/app/api/mailsModels.py b/backend/app/api/mailsModels.py index b92ee26..c64d0dd 100644 --- a/backend/app/api/mailsModels.py +++ b/backend/app/api/mailsModels.py @@ -63,6 +63,8 @@ def getMailContent(mail_type, args): else: raise Exception("Unknown mail type !") + obj = mail[0] + content = str(mail[1]) for key, value in args.items(): - mail[1].replace("#" + key, value) - return mail + content = content.replace("#" + key, value) + return (obj, content) diff --git a/backend/app/model.py b/backend/app/model.py index 6179978..5861f3b 100644 --- a/backend/app/model.py +++ b/backend/app/model.py @@ -75,15 +75,59 @@ def getGroup(gid=0, name=""): return None -def getTutorshipForStudent(gid, student): - query = TUTORSHIP.select(and_(TUTORSHIP.c.group_id == gid, TUTORSHIP.c.student_id == student)) - rows = query.execute() - res = rows.first() - if res is not None: - return {"id": res.id, "group_id": getGroup(gid=res.group_id), "student_id": getUser(uid=res.student_id), - "ptutor_id": getUser(uid=res.ptutor_id)} +def getTutorship(tid=0, gid=0, student=0): + if tid == 0 and gid == 0 and student == 0: + raise Exception("getGroup must be called with at least one argument !") else: - return None + if gid != 0: + query = TUTORSHIP.select(and_(TUTORSHIP.c.group_id == gid, TUTORSHIP.c.student_id == student)) + rows = query.execute() + res = rows.first() + elif tid != 0: + query = TUTORSHIP.select(TUTORSHIP.c.id == tid) + rows = query.execute() + res = rows.first() + else: + raise Exception("getTutorship must be called with two parameter for group+student search !") + + if res is not None: + return {"id": res.id, "group_id": getGroup(gid=res.group_id), "student_id": getUser(uid=res.student_id), + "ptutor_id": getUser(uid=res.ptutor_id)} + else: + return None + + +def getLivret(lid=0, group_id=0, student_id=0): + res = None + + if lid == 0 and student_id == "": + raise Exception("getLivret must be called with at least one argument !") + else: + if lid != 0: + query = LIVRET.select(LIVRET.c.id == lid) + rows = query.execute() + res = rows.first() + + elif student_id != 0 and group_id != 0: + tutorship = getTutorship(gid=group_id, student=student_id) + if tutorship is None: + return None + query = LIVRET.select(LIVRET.c.tutorship_id == tutorship["id"]) + rows = query.execute() + res = rows.first() + else: + raise Exception("getLivret must be called with two parameter for group+student search !") + + if res is not None: + return {"id": res.id, "tutorship_id": getTutorship(tid=res.tutorship_id), + "etutor_id": getUser(uid=res.etutor_id), "company_name": res.company_name, + "company_address": res.company_address, "contract_type": res.contract_type, + "contract_start": res.contract_start.strftime('%d-%m-%Y'), + "contract_end": res.contract_end.strftime('%d-%m-%Y'), + "ressources_dir": res.ressources_dir, "opened": res.opened, + "expire": res.expire.strftime('%d-%m-%Y')} + else: + return None def hashExists(test): diff --git a/backend/app/urls.py b/backend/app/urls.py index 5ccd60b..2a0027d 100644 --- a/backend/app/urls.py +++ b/backend/app/urls.py @@ -14,4 +14,5 @@ api.add_resource(UserGroupsAPI, '/api/userGroups') api.add_resource(UserAPI, '/api/user', '/api/user/byuid/', '/api/user/byemail/', '/api/user/byhash/') api.add_resource(GroupAPI, '/api/group', '/api/group/bygid/', '/api/group/byname/') -api.add_resource(LivretAPI, '/api/livret', '/api/livret/byuid/') +api.add_resource(LivretAPI, '/api/livret', '/api/livret/bylid/', + '/api/livret/bytutorship//')