Adicionar endpoint: POST /trainer/authenticate

This commit is contained in:
Augusto Gunsch
2021-10-17 21:14:56 -03:00
parent fffcb5aa45
commit 7f7dbd68d0
5 changed files with 86 additions and 20 deletions

18
api/views/errors.py Normal file
View File

@@ -0,0 +1,18 @@
def error(code, type, message, http_code=400):
return ({
"code": code,
"type": type,
"message": message
}, http_code)
def ParsingError(message):
return error(1, "ParsingError", message)
def ConflictingParameters(message):
return error(2, "ConflictingParameters", message)
def ConflictingResources(message):
return error(3, "ConflictingResources", message, http_code=409)
def AuthenticationFailure(message):
return error(4, "AuthenticationFailure", message, http_code=401)

View File

@@ -1,18 +1,18 @@
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
from flask import request, jsonify
# função auxiliar
def error(code, type, message, http_code=400):
return ({
"code": code,
"type": type,
"message": message
}, http_code)
from .errors import ParsingError, ConflictingParameters, ConflictingResources, AuthenticationFailure
from werkzeug.security import check_password_hash
import datetime
import jwt
def get_trainer(id):
return trainer_schema.dump(Trainer.query.get(id))
try:
return trainer_schema.dump(Trainer.query.get(id))
except:
return jsonify({})
def get_trainers():
args = request.args
@@ -21,10 +21,10 @@ def get_trainers():
limit = int(args.get("limit", -1))
offset = int(args.get("offset", 0))
except ValueError:
return error(0, "ParsingError", "Couldn't parse parameter as integer")
return ParsingError("Couldn't parse parameter as integer")
if limit < -1 or offset < 0:
return error(1, "ParsingError", "Expected positive integer as parameter")
return ParsingError("Expected positive integer as parameter")
nickname = args.get("nickname", "")
nickname_contains = args.get("nickname_contains", "")
@@ -32,7 +32,7 @@ def get_trainers():
try:
if nickname:
if nickname_contains:
return error(2, "ConflictingParameters", "nickname and nickname_contains are mutually exclusive")
return ConflictingParameters("nickname and nickname_contains are mutually exclusive")
query = Trainer.query.filter_by(nickname=nickname)
return trainer_schemas.dumps(query.all())
@@ -45,14 +45,20 @@ def get_trainers():
except NoResultFound:
return jsonify([])
def get_trainer_by_email(email):
try:
return Trainer.query.filter_by(email=email).one()
except:
return None
def post_trainer():
try:
json = request.get_json()
except:
return error(3, "ParsingError", "Failed to parse JSON content")
return ParsingError("Failed to parse JSON body")
if type(json) is not dict:
return error(4, "ParsingError", "Expected JSON object as content")
return ParsingError("Expected JSON object as body")
try:
nickname = json["nickname"]
@@ -76,8 +82,42 @@ def post_trainer():
return trainer_schema.dump(trainer)
except InvalidTeam:
return error(5, "ParsingError", "Field team is invalid")
return ParsingError("Field team is invalid")
except KeyError:
return error(6, "ParsingError", "Missing JSON object fields")
return ParsingError("Missing JSON object fields")
except IntegrityError:
return error(7, "ConflictingResource", "Trainer with the same nickname or email already exists", http_code=500)
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")