diff --git a/app.py b/app.py index 73e0e76..5c5c7dc 100644 --- a/app.py +++ b/app.py @@ -3,8 +3,8 @@ from flask import Flask from flask_restful import Api from flask_cors import CORS -# from flask_jwt import JWT -#from security import authenticate, identity +from flask_jwt import JWT +from security import authenticate, identity # import resorces from resources.raw_material import * @@ -19,15 +19,14 @@ app.config['DEBUG'] = True app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///data.db') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - app.secret_key = 'rebequinha' # creates API instance CORS(app) api = Api(app) - -# jwt = JWT(app, authenticate, identity) # /auth +# creates jwt functionality for user authentication (/auth) +jwt = JWT(app, authenticate, identity) # Sets up API endpoints api.add_resource(RawMaterial, '/raw_materials/') @@ -44,7 +43,6 @@ api.add_resource(Orders, '/orders') # api.add_resource(UserRegister, '/register') - if __name__ == '__main__': from db import db @@ -55,4 +53,11 @@ def create_tables(): db.create_all() + # creates an admin user before initializing the app + from models.user import UserModel + adminUser = UserModel("admin",os.environ.get('ADMIN_PASSWORD', 'testeAdmin')) + adminUser.save_to_db() + app.run(port=5000) + + diff --git a/data.db b/data.db index 1da1fbd..91d8993 100644 Binary files a/data.db and b/data.db differ diff --git a/models/recipe.py b/models/recipe.py index c0de909..7609fb4 100644 --- a/models/recipe.py +++ b/models/recipe.py @@ -31,7 +31,7 @@ def json(self): 'last_update' : self.last_update, 'labor_cost' : self.labor_cost, 'supply_cost' : self.supply_cost, - 'materials' : self.materials + 'materials' : [material.id for material in self.materials] } def save_to_db(self): @@ -50,5 +50,5 @@ def find_by_description(cls, description): def find_by_id(cls, id_): return cls.query.filter_by(id=id_).first() - def get_all_materials(self): - return self.materials + def get_materials(self): + return [material.json() for material in self.materials] diff --git a/models/user.py b/models/user.py new file mode 100644 index 0000000..7eafb49 --- /dev/null +++ b/models/user.py @@ -0,0 +1,30 @@ +from db import db + +class UserModel(db.Model): + __tablename__ = 'users' + + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(80)) + password = db.Column(db.String(80)) + + def __init__(self, username, password): + self.username = username + self.password = password + + def save_to_db(self): + db.session.add(self) + db.session.commit() + + def json(self): + return {'id' : self.id, + 'username' : self.username, + 'password' : self.password, + } + + @classmethod + def find_by_username(cls, username): + return cls.query.filter_by(username=username).first() + + @classmethod + def find_by_id(cls, _id): + return cls.query.filter_by(id=_id).first() \ No newline at end of file diff --git a/resources/recipe.py b/resources/recipe.py index 3c82b3a..cb8eb15 100644 --- a/resources/recipe.py +++ b/resources/recipe.py @@ -8,6 +8,7 @@ # import model from models.recipe import RecipeModel +from models.raw_material import RawMaterialModel class Recipe(Resource): @@ -16,6 +17,7 @@ class Recipe(Resource): parser.add_argument('description',type=str,required=False) parser.add_argument('labor_cost',type=float,required=False) parser.add_argument('supply_cost',type=float,required=False) + parser.add_argument('materials',type=int, action='append',required=False) # to handle HTTP GET /recipe?id= def get(self, id): @@ -53,12 +55,21 @@ def put(self, id): if key=='sell_by_date': recipe.sell_by_date = data['sell_by_date'] if key=='materials': - pass + recipe.materials.clear() + for id in data['materials']: + material = RawMaterialModel.find_by_id(id) + if material: + recipe.materials.append(material) + recipe.last_update = datetime.now().strftime("%d/%m/%Y %H:%M") # in case not exist, creates a new item else: - recipe = RecipeModel(**data) + recipe = RecipeModel(data['description'],data['labor_cost'],data['supply_cost']) + for id in data['materials']: + material = RawMaterialModel.find_by_id(id) + if material: + recipe.materials.append(material) # tries to insert in database # returns 500 (internal server error) in case of database failure @@ -77,6 +88,7 @@ class Recipes(Resource): parser.add_argument('description',type=str,required=True) parser.add_argument('labor_cost',type=float,required=True) parser.add_argument('supply_cost',type=float,required=True) + parser.add_argument('materials',type=int, action='append',required=True) # handles HTTP request GET /recipes def get(self): @@ -96,8 +108,14 @@ def post(self): # in case it does not exist, creates a new recipe using data passed # along with the HTTP request - recipe = RecipeModel(**data) - + recipe = RecipeModel(data['description'],data['labor_cost'],data['supply_cost']) + + # links the recipe to all related materials + for id in data['materials']: + material = RawMaterialModel.find_by_id(id) + if material: + recipe.materials.append(material) + # tries to insert in database # returns 500 (internal server error) in case of database failure try: @@ -112,10 +130,8 @@ def post(self): class MaterialList(Resource): # route: recipe//materials def get(self, id): - recipe = RecipeModel.find_by_id(id) - if recipe: - return {[x.json() for x in recipe.get_all_materials()]} + return recipe.get_materials() else: return {'message' : constants['ID_NOT_FOUND']} \ No newline at end of file diff --git a/security.py b/security.py new file mode 100644 index 0000000..1107206 --- /dev/null +++ b/security.py @@ -0,0 +1,11 @@ +from werkzeug.security import safe_str_cmp +from models.user import UserModel + +def authenticate(username, password): + user = UserModel.find_by_username(username) + if user and safe_str_cmp(password,user.password): + return user + +def identity(payload): + user_id = payload['identity'] + return UserModel.find_by_id(user_id) \ No newline at end of file