Pequena limpeza

This commit is contained in:
Augusto Gunsch 2021-10-19 00:43:26 -03:00
parent d6caab7f7b
commit 27b8fcf215
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
5 changed files with 31 additions and 34 deletions

View File

@ -2,6 +2,6 @@ import string
import random import random
random_str = string.ascii_letters + string.digits + string.ascii_uppercase random_str = string.ascii_letters + string.digits + string.ascii_uppercase
SECRET_KEY = ''.join(random.choice(random_str) for i in range(12)) SECRET_KEY = ''.join(random.choice(random_str) for _ in range(12))
SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False

View File

@ -1,6 +1,5 @@
from api.app import app from api.app import app
from api.views import trainer, pokemon_owned, helper, errors from api.views import trainer, pokemon_owned, authentication, errors
from flask import request
import asyncio import asyncio
@app.route("/trainer/<int:trainerId>", methods=["GET"]) @app.route("/trainer/<int:trainerId>", methods=["GET"])
@ -24,7 +23,7 @@ def route_get_pokemons_owned(trainerId):
return asyncio.run(pokemon_owned.get_pokemons_owned(trainerId)) return asyncio.run(pokemon_owned.get_pokemons_owned(trainerId))
@app.route("/trainer/<int:trainerId>/pokemon", methods=["POST"]) @app.route("/trainer/<int:trainerId>/pokemon", methods=["POST"])
@helper.token_required @authentication.token_required
def route_post_pokemons_owned(trainer, trainerId): def route_post_pokemons_owned(trainer, trainerId):
if trainer.id != trainerId: if trainer.id != trainerId:
return errors.ForbiddenError("Trainer id mismatch") return errors.ForbiddenError("Trainer id mismatch")
@ -35,7 +34,7 @@ def route_get_pokemon_owned(trainerId, pokemonId):
return pokemon_owned.get_pokemon_owned(trainerId, pokemonId) return pokemon_owned.get_pokemon_owned(trainerId, pokemonId)
@app.route("/trainer/<int:trainerId>/pokemon/<int:pokemonId>", methods=["DELETE"]) @app.route("/trainer/<int:trainerId>/pokemon/<int:pokemonId>", methods=["DELETE"])
@helper.token_required @authentication.token_required
def route_delete_pokemon_owned(trainer, trainerId, pokemonId): def route_delete_pokemon_owned(trainer, trainerId, pokemonId):
if trainer.id != trainerId: if trainer.id != trainerId:
return errors.ForbiddenError("Trainer id mismatch") return errors.ForbiddenError("Trainer id mismatch")

View File

@ -0,0 +1,25 @@
from functools import wraps
from flask import request
from api.app import app
from .fetch import get_trainer_by_nick_fail, NotFound
from .errors import AuthenticationFailure
import jwt
# authenticação do trainer (decorator)
def token_required(f):
@wraps(f)
def decorated(*args, **kwargs):
try:
token = request.headers["authorization"]
data = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])
trainer = get_trainer_by_nick_fail(data["username"])
except (TypeError, KeyError):
return AuthenticationFailure("JWT token required")
except NotFound:
return AuthenticationFailure("Trainer not found")
except:
return AuthenticationFailure("JWT token is invalid or expired")
return f(trainer, *args, **kwargs)
return decorated

View File

@ -1,15 +1,6 @@
from functools import wraps
from flask import request
from api.models.trainer import Trainer from api.models.trainer import Trainer
from .errors import AuthenticationFailure
from api.app import app
import requests import requests
import json import json
import jwt
class HTTPError(Exception):
def __init__(self, message):
self.message = message
class NotFound(Exception): class NotFound(Exception):
def __init__(self, message): def __init__(self, message):
@ -33,25 +24,7 @@ def get_trainer_by_nick_fail(nickname):
def get_pokemon_fail(trainer, id): def get_pokemon_fail(trainer, id):
return get_or_not_found(lambda : trainer.pokemons_list.filter_by(id=id).one()) return get_or_not_found(lambda : trainer.pokemons_list.filter_by(id=id).one())
# authenticação do trainer (decorator) # helper interno
def token_required(f):
@wraps(f)
def decorated(*args, **kwargs):
try:
token = request.headers["authorization"]
data = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])
trainer = get_trainer_by_nick_fail(data["username"])
except (TypeError, KeyError):
return AuthenticationFailure("JWT token required")
except NotFound:
return AuthenticationFailure("Trainer not found")
except:
return AuthenticationFailure("JWT token is invalid or expired")
return f(trainer, *args, **kwargs)
return decorated
# helpers internos
def cant_fetch_error(pokemon): def cant_fetch_error(pokemon):
raise NotFound("Could not fetch data for pokemon with id {}".format(pokemon.pokemon_id)) raise NotFound("Could not fetch data for pokemon with id {}".format(pokemon.pokemon_id))

View File

@ -2,7 +2,7 @@ from api.models.pokemon_owned import pokemon_owned_schema, pokemon_owned_schemas
from api.app import db from api.app import db
from .parse_args import parse_limit, parse_offset, ParsingException, parse_json_obj from .parse_args import parse_limit, parse_offset, ParsingException, parse_json_obj
from .errors import ParsingError, FetchError, ConflictingResources from .errors import ParsingError, FetchError, ConflictingResources
from .helper import * from .fetch import *
from aiohttp import ClientSession from aiohttp import ClientSession
import asyncio import asyncio
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError