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_DATABASE_URI = 'sqlite:///database.db'
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from api.app import db, ma
|
from api.app import db, ma
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
teams = (
|
teams = (
|
||||||
"Team Valor",
|
"Team Valor",
|
||||||
|
@ -16,10 +15,10 @@ class Trainer(db.Model):
|
||||||
__tablename__ = "trainers"
|
__tablename__ = "trainers"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
|
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)
|
first_name = db.Column(db.String(30), nullable=False)
|
||||||
last_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)
|
password = db.Column(db.String(200), nullable=False)
|
||||||
team = db.Column(db.String(10), nullable=False)
|
team = db.Column(db.String(10), nullable=False)
|
||||||
pokemons_owned = db.Column(db.Integer, default=0)
|
pokemons_owned = db.Column(db.Integer, default=0)
|
||||||
|
|
|
@ -14,3 +14,7 @@ def route_get_trainers():
|
||||||
@app.route('/trainer', methods=['POST'])
|
@app.route('/trainer', methods=['POST'])
|
||||||
def route_create_trainer():
|
def route_create_trainer():
|
||||||
return trainer.post_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 sqlalchemy.exc import NoResultFound, IntegrityError
|
||||||
from api.models.trainer import Trainer, trainer_schema, trainer_schemas, InvalidTeam
|
from api.models.trainer import Trainer, trainer_schema, trainer_schemas, InvalidTeam
|
||||||
from api.app import db
|
from api.app import db
|
||||||
|
from api.app import app
|
||||||
from flask import request, jsonify
|
from flask import request, jsonify
|
||||||
|
from .errors import ParsingError, ConflictingParameters, ConflictingResources, AuthenticationFailure
|
||||||
# função auxiliar
|
from werkzeug.security import check_password_hash
|
||||||
def error(code, type, message, http_code=400):
|
import datetime
|
||||||
return ({
|
import jwt
|
||||||
"code": code,
|
|
||||||
"type": type,
|
|
||||||
"message": message
|
|
||||||
}, http_code)
|
|
||||||
|
|
||||||
def get_trainer(id):
|
def get_trainer(id):
|
||||||
|
try:
|
||||||
return trainer_schema.dump(Trainer.query.get(id))
|
return trainer_schema.dump(Trainer.query.get(id))
|
||||||
|
except:
|
||||||
|
return jsonify({})
|
||||||
|
|
||||||
def get_trainers():
|
def get_trainers():
|
||||||
args = request.args
|
args = request.args
|
||||||
|
@ -21,10 +21,10 @@ def get_trainers():
|
||||||
limit = int(args.get("limit", -1))
|
limit = int(args.get("limit", -1))
|
||||||
offset = int(args.get("offset", 0))
|
offset = int(args.get("offset", 0))
|
||||||
except ValueError:
|
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:
|
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 = args.get("nickname", "")
|
||||||
nickname_contains = args.get("nickname_contains", "")
|
nickname_contains = args.get("nickname_contains", "")
|
||||||
|
@ -32,7 +32,7 @@ def get_trainers():
|
||||||
try:
|
try:
|
||||||
if nickname:
|
if nickname:
|
||||||
if nickname_contains:
|
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)
|
query = Trainer.query.filter_by(nickname=nickname)
|
||||||
return trainer_schemas.dumps(query.all())
|
return trainer_schemas.dumps(query.all())
|
||||||
|
@ -45,14 +45,20 @@ def get_trainers():
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
return jsonify([])
|
return jsonify([])
|
||||||
|
|
||||||
|
def get_trainer_by_email(email):
|
||||||
|
try:
|
||||||
|
return Trainer.query.filter_by(email=email).one()
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def post_trainer():
|
def post_trainer():
|
||||||
try:
|
try:
|
||||||
json = request.get_json()
|
json = request.get_json()
|
||||||
except:
|
except:
|
||||||
return error(3, "ParsingError", "Failed to parse JSON content")
|
return ParsingError("Failed to parse JSON body")
|
||||||
|
|
||||||
if type(json) is not dict:
|
if type(json) is not dict:
|
||||||
return error(4, "ParsingError", "Expected JSON object as content")
|
return ParsingError("Expected JSON object as body")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nickname = json["nickname"]
|
nickname = json["nickname"]
|
||||||
|
@ -76,8 +82,42 @@ def post_trainer():
|
||||||
|
|
||||||
return trainer_schema.dump(trainer)
|
return trainer_schema.dump(trainer)
|
||||||
except InvalidTeam:
|
except InvalidTeam:
|
||||||
return error(5, "ParsingError", "Field team is invalid")
|
return ParsingError("Field team is invalid")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return error(6, "ParsingError", "Missing JSON object fields")
|
return ParsingError("Missing JSON object fields")
|
||||||
except IntegrityError:
|
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