Adicionar endpoint: POST /trainer/authenticate
This commit is contained in:
parent
fffcb5aa45
commit
7f7dbd68d0
|
@ -1,2 +1,7 @@
|
|||
import string
|
||||
import random
|
||||
|
||||
random_str = string.ascii_letters + string.digits + string.ascii_uppercase
|
||||
SECRET_KEY = ''.join(random.choice(random_str) for i in range(12))
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db'
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from api.app import db, ma
|
||||
from werkzeug.security import generate_password_hash
|
||||
from enum import Enum
|
||||
|
||||
teams = (
|
||||
"Team Valor",
|
||||
|
@ -16,10 +15,10 @@ class Trainer(db.Model):
|
|||
__tablename__ = "trainers"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
|
||||
nickname = db.Column(db.String(20), nullable=False, index=True)
|
||||
nickname = db.Column(db.String(20), unique=True, nullable=False, index=True)
|
||||
first_name = db.Column(db.String(30), nullable=False)
|
||||
last_name = db.Column(db.String(30), nullable=False)
|
||||
email = db.Column(db.String(60), unique=True, nullable=False)
|
||||
email = db.Column(db.String(60), unique=True, index=True, nullable=False)
|
||||
password = db.Column(db.String(200), nullable=False)
|
||||
team = db.Column(db.String(10), nullable=False)
|
||||
pokemons_owned = db.Column(db.Integer, default=0)
|
||||
|
|
|
@ -14,3 +14,7 @@ def route_get_trainers():
|
|||
@app.route('/trainer', methods=['POST'])
|
||||
def route_create_trainer():
|
||||
return trainer.post_trainer()
|
||||
|
||||
@app.route("/trainer/authenticate", methods=['POST'])
|
||||
def route_auth_trainer():
|
||||
return trainer.auth_trainer()
|
||||
|
|
|
@ -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)
|
|
@ -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):
|
||||
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")
|
||||
|
|
Loading…
Reference in New Issue