from flask import Flask, abort, jsonify, url_for, render_template, g, request from flask.json import JSONEncoder from flask_sqlalchemy import SQLAlchemy from flask_httpauth import HTTPBasicAuth import decimal, re, json from passlib.apps import custom_app_context as pwd_context from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired) app = Flask(__name__) app.config['SECRET_KEY'] = 'geunyeorang cheoeum daehoa sijag hajamaja' app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://ruvadmin:ge9BQ7fT8bVBgm1B@localhost/ruvapp' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True db = SQLAlchemy(app) auth = HTTPBasicAuth() class MJSONEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, decimal.Decimal): # Convert decimal instances to strings. return str(obj) return super(MJSONEncoder, self).default(obj) app.json_encoder = MJSONEncoder class User(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True) password_hash = db.Column(db.String(128)) def hash_password(self, password): self.password_hash = pwd_context.encrypt(password) print(self.password_hash) def verify_password(self, password): return pwd_context.verify(password, self.password_hash) def generate_auth_token(self, expiration=600): s = Serializer(app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'id': self.id}) @staticmethod def verify_auth_token(token): print ('48 - ' + token) s = Serializer(app.config['SECRET_KEY']) try: data = s.loads(token) except SignatureExpired: return None # valid token, but expired except BadSignature: return None # invalid token user = User.query.get(data['id']) if user is None: return return user class Roof(db.Model): __tablename__ = "roofs" id = db.Column(db.Integer, primary_key=True) length = db.Column(db.DECIMAL(10, 3)) width = db.Column(db.DECIMAL(10, 3)) slope = db.Column(db.Float) price = db.Column(db.DECIMAL(10, 2)) address = db.Column(db.VARCHAR(255)) def serialize(self): return { 'id': self.id, 'length': re.sub("[^0-9^.]", "", str(self.length)), 'width': re.sub("[^0-9^.]", "", str(self.width)), 'slope': re.sub("[^0-9^.]", "", str(self.slope)), 'price': re.sub("[^0-9^.]", "", str(self.price)), 'address': self.address.encode("utf-8"), } @auth.verify_password def verify_password(email_or_token, password): # first try to authenticate by token user = User.verify_auth_token(email_or_token) if not user: # try to authenticate with username/password user = User.query.filter_by(email=email_or_token).first() print ('86') print (user) if not user or not user.verify_password(password): return False g.user = user return True @app.route('/') def index(): return render_template('index.html') @app.route('/login', methods=['POST']) def login(): if request.headers['content-Type'] == 'application/x-www-form-urlencoded': email = request.form['email'] password = request.form['password'] if email is None or password is None: abort(400) if User.query.filter_by(email=email).first() is not None: verify = verify_password(email, password) user = User(email=email) print('108 - ' + verify) if verify: print('You already in there\n') return render_template('success.html') else: print ('Login failed') return 'Login failed' user = User(email=email) User.hash_password(user, password) db.session.add(user) db.session.commit() return render_template('success.html') elif request.headers['Content-Type'] == 'application/json': print ('122') print(request.json) email = request.json.get('email') password = request.json.get('password') if email is None or password is None: abort(400) if User.query.filter_by(email=email).first() is not None: verify = verify_password(email, password) user = User(email=email) print ('130') print (verify) if verify: print (g.user.id) token = g.user.generate_auth_token(600) return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, { 'Location': url_for('get_user', id=g.user.id, _external=True)} else: print ('Error: Login Unsuccessful') return 'Error: Login Unsuccessful' user = User(email=email) User.hash_password(user, password) db.session.add(user) db.session.commit() verify_password(email, password) token = g.user.generate_auth_token(600) return jsonify({'email': user.email, 'authToken': token.decode('ascii')}), 201, {'Location': url_for('get_user', id=user.id, _external=True)} @app.route('/roof/add', methods=['POST']) @auth.login_required def add_roof(): print ('Requesting roof addition') if request.headers['Content-Type'] == 'application/json': print ('155') print (request.json) length = request.json.get('length') width = request.json.get('width') slope = request.json.get('slope') address = request.json.get('address') price = request.json.get('price') if length is None or width is None or slope is None or address is None or price is None: print ('Something not set') abort(400) if Roof.query.filter_by(address=address).first() is not None: roof = Roof(address=address, price=price) print ('Found a roof') if roof is not None: print ('Roof is not None') print (str(roof.serialize())) return jsonify({'Roof': roof.serialize()}), 201 print ('Make new roof') roof = Roof(address=address, length=length, width=width, slope=slope, price=price) db.session.add(roof) db.session.commit() print ('Created roof==> ' + str(roof.serialize())) return jsonify({'Roof': roof.serialize()}), 201, { 'Location': url_for('get_roof', address=roof.address, _external=True)} @app.route('/users/') @auth.login_required def get_user(id): user = User.query.get(id) if not user: abort(400) return jsonify({'email': user.email, 'password': user.password_hash}) @app.route('/roofs/') @auth.login_required def get_roof(id): roof = Roof.query.get(id) if not roof: abort(400) return jsonify({'Roof': roof.serialize()}) @app.route('/token') @auth.login_required def get_auth_token(): token = g.user.generate_auth_token(600) return jsonify({'token': token.decode('ascii'), 'duration': 600}) @app.route('/resource') @auth.login_required def get_resource(): return jsonify({'data': 'Hello, %s!' % g.user.email}) @app.route('/roofs/all', methods=['GET']) @auth.login_required def get_roofs(): roofs = Roof.query.all() rStr = '' mJson = '' rlist = [None] * 10 i = 0 for roof in roofs: # rStr += str(jsonify({i: (roof.serialize())})) mJson += '{"roof":' + str(roof.serialize()).replace("'", '"') + '},' rStr += (str([(str(i) + ":" + str((roof.serialize())))])) rObj = (["\""+str(i)+"\"", str(roof.serialize())]) rlist.append(["roof", rObj]) i += 1 # rStr = ("[" + rStr[:-1] + "]") mJson = '{"Roofs":[' + str((mJson[:-1])) + ']}' # rjson = json.dumps(rStr.replace('\\n', '\n').replace('\"', '"')) if not roofs: abort(400) # return jsonify({'Roofs': rStr.replace("\\", "")}), 201 # return jsonify({'Roofs': str(rStr).replace('\\n', '\n').replace('\"', '"')}), 201 return (mJson.replace('\\"', '"')), 201 def json_list(list): lst = [] for pn in list: d = {} d['roof']=pn lst.append(d) return json.dumps(lst) if __name__ == '__main__': app.debug = True # app.debug = False app.run()