├── requirements.txt └── app.py /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | datetime 3 | uuid 4 | Flask-SQLAlchemy 5 | PyJWT 6 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify, make_response 2 | from flask_sqlalchemy import SQLAlchemy 3 | from werkzeug.security import generate_password_hash, check_password_hash 4 | import uuid 5 | import jwt 6 | import datetime 7 | from functools import wraps 8 | 9 | app = Flask(__name__) 10 | 11 | app.config['SECRET_KEY']='Th1s1ss3cr3t' 12 | app.config['SQLALCHEMY_DATABASE_URI']='sqlite://///home/michael/geekdemos/geekapp/library.db' 13 | app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 14 | 15 | db = SQLAlchemy(app) 16 | 17 | class Users(db.Model): 18 | id = db.Column(db.Integer, primary_key=True) 19 | public_id = db.Column(db.Integer) 20 | name = db.Column(db.String(50)) 21 | password = db.Column(db.String(50)) 22 | admin = db.Column(db.Boolean) 23 | 24 | class Authors(db.Model): 25 | id = db.Column(db.Integer, primary_key=True) 26 | name = db.Column(db.String(50), unique=True, nullable=False) 27 | book = db.Column(db.String(20), unique=True, nullable=False) 28 | country = db.Column(db.String(50), nullable=False) 29 | booker_prize = db.Column(db.Boolean) 30 | user_id = db.Column(db.Integer) 31 | 32 | 33 | def token_required(f): 34 | @wraps(f) 35 | def decorator(*args, **kwargs): 36 | 37 | token = None 38 | 39 | if 'x-access-tokens' in request.headers: 40 | token = request.headers['x-access-tokens'] 41 | 42 | 43 | if not token: 44 | return jsonify({'message': 'a valid token is missing'}) 45 | 46 | 47 | try: 48 | data = jwt.decode(token, app.config[SECRET_KEY]) 49 | current_user = Users.query.filter_by(public_id=data['public_id']).first() 50 | except: 51 | return jsonify({'message': 'token is invalid'}) 52 | 53 | 54 | return f(current_user, *args, **kwargs) 55 | return decorator 56 | 57 | 58 | 59 | 60 | @app.route('/register', methods=['GET', 'POST']) 61 | def signup_user(): 62 | data = request.get_json() 63 | 64 | hashed_password = generate_password_hash(data['password'], method='sha256') 65 | 66 | new_user = Users(public_id=str(uuid.uuid4()), name=data['name'], password=hashed_password, admin=False) 67 | db.session.add(new_user) 68 | db.session.commit() 69 | 70 | return jsonify({'message': 'registered successfully'}) 71 | 72 | 73 | @app.route('/login', methods=['GET', 'POST']) 74 | def login_user(): 75 | 76 | auth = request.authorization 77 | 78 | if not auth or not auth.username or not auth.password: 79 | return make_response('could not verify', 401, {'WWW.Authentication': 'Basic realm: "login required"'}) 80 | 81 | user = Users.query.filter_by(name=auth.username).first() 82 | 83 | if check_password_hash(user.password, auth.password): 84 | token = jwt.encode({'public_id': user.public_id, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, app.config['SECRET_KEY']) 85 | return jsonify({'token' : token.decode('UTF-8')}) 86 | 87 | return make_response('could not verify', 401, {'WWW.Authentication': 'Basic realm: "login required"'}) 88 | 89 | 90 | @app.route('/user', methods=['GET']) 91 | def get_all_users(): 92 | 93 | users = Users.query.all() 94 | 95 | result = [] 96 | 97 | for user in users: 98 | user_data = {} 99 | user_data['public_id'] = user.public_id 100 | user_data['name'] = user.name 101 | user_data['password'] = user.password 102 | user_data['admin'] = user.admin 103 | 104 | result.append(user_data) 105 | 106 | return jsonify({'users': result}) 107 | 108 | 109 | @app.route('/authors', methods=['GET', 'POST']) 110 | @token_required 111 | def get_authors(current_user, public_id): 112 | 113 | authors = Authors.query.all() 114 | 115 | output = [] 116 | 117 | for author in authors: 118 | author_data = {} 119 | author_data['name'] = author.name 120 | author_data['book'] = author.book 121 | author_data['country'] = author.country 122 | author_data['booker_prize'] = author.booker_prize 123 | output.append(author_data) 124 | 125 | return jsonify({'list_of_authors' : output}) 126 | 127 | 128 | 129 | @app.route('/authors', methods=['POST', 'GET']) 130 | @token_required 131 | def create_author(current_user): 132 | 133 | data = request.get_json() 134 | 135 | new_authors = Authors(name=data['name'], country=data['country'], book=data['book'], booker_prize=True, user_id=current_user.id) 136 | db.session.add(new_authors) 137 | db.session.commit() 138 | 139 | return jsonify({'message' : 'new author created'}) 140 | 141 | 142 | 143 | 144 | @app.route('/authors/', methods=['DELETE']) 145 | @token_required 146 | def delete_author(current_user, name): 147 | author = Author.query.filter_by(name=name, user_id=current_user.id).first() 148 | if not author: 149 | return jsonify({'message': 'author does not exist'}) 150 | 151 | 152 | db.session.delete(author) 153 | db.session.commit() 154 | 155 | return jsonify({'message': 'Author deleted'}) 156 | 157 | 158 | if __name__ == '__main__': 159 | app.run(debug=True) 160 | --------------------------------------------------------------------------------