cake-erp-challenge/api/views/trainer.py

124 lines
3.8 KiB
Python
Raw Normal View History

2021-10-17 17:59:27 -04:00
from sqlalchemy.exc import NoResultFound, IntegrityError
from api.models.trainer import Trainer, trainer_schema, trainer_schemas, InvalidTeam
from api.app import db
from api.app import app
2021-10-17 17:59:27 -04:00
from flask import request, jsonify
from .errors import ParsingError, ConflictingParameters, ConflictingResources, AuthenticationFailure
from werkzeug.security import check_password_hash
import datetime
import jwt
2021-10-17 17:59:27 -04:00
def get_trainer(id):
try:
return trainer_schema.dump(Trainer.query.get(id))
except:
return jsonify({})
2021-10-17 17:59:27 -04:00
def get_trainers():
args = request.args
try:
limit = int(args.get("limit", -1))
offset = int(args.get("offset", 0))
except ValueError:
return ParsingError("Couldn't parse parameter as integer")
2021-10-17 17:59:27 -04:00
if limit < -1 or offset < 0:
return ParsingError("Expected positive integer as parameter")
2021-10-17 17:59:27 -04:00
nickname = args.get("nickname", "")
nickname_contains = args.get("nickname_contains", "")
try:
if nickname:
if nickname_contains:
return ConflictingParameters("nickname and nickname_contains are mutually exclusive")
2021-10-17 17:59:27 -04:00
query = Trainer.query.filter_by(nickname=nickname).limit(limit).offset(offset)
2021-10-17 17:59:27 -04:00
return trainer_schemas.dumps(query.all())
else: # se nickname_contains também está vazio, retornará todos trainers
pattern = '%'+nickname_contains+'%'
query = Trainer.query.filter(Trainer.nickname.like(pattern)).limit(limit).offset(offset)
2021-10-17 17:59:27 -04:00
return trainer_schemas.dumps(query.all())
except NoResultFound:
return jsonify([])
def get_trainer_by_email(email):
try:
return Trainer.query.filter_by(email=email).one()
except:
return None
2021-10-17 17:59:27 -04:00
def post_trainer():
try:
json = request.get_json()
except:
return ParsingError("Failed to parse JSON body")
2021-10-17 17:59:27 -04:00
if type(json) is not dict:
return ParsingError("Expected JSON object as body")
2021-10-17 17:59:27 -04:00
try:
nickname = json["nickname"]
first_name = json["first_name"]
last_name = json["last_name"]
email = json["email"]
password = json["password"]
team = json["team"]
trainer = Trainer(
nickname=nickname,
first_name=first_name,
last_name=last_name,
email=email,
password=password,
team=team
)
db.session.add(trainer)
db.session.commit()
return trainer_schema.dump(trainer)
except InvalidTeam:
return ParsingError("Field team is invalid")
2021-10-17 17:59:27 -04:00
except KeyError:
return ParsingError("Missing JSON object fields")
2021-10-17 17:59:27 -04:00
except IntegrityError:
return ConflictingResources("Trainer with the same nickname or email already exists", http_code=500)
def auth_trainer():
try:
auth = request.get_json()
except:
return ParsingError("Failed to parse JSON body")
if type(auth) is not dict:
return ParsingError("Expected JSON object as body")
try:
email = auth["email"]
password = auth["password"]
except KeyError:
return AuthenticationFailure("Login required")
trainer = get_trainer_by_email(email)
if not trainer:
return AuthenticationFailure("Trainer not found")
if trainer and check_password_hash(trainer.password, password):
token = jwt.encode(
{
"username": trainer.nickname,
"exp": datetime.datetime.now() + datetime.timedelta(hours=12)
},
app.config["SECRET_KEY"])
return jsonify(
{
"id": trainer.id,
"token": token
})
return AuthenticationFailure("Invalid login")