def stock(stock_id=''): res = ApiResponse() try: if request.method == 'GET': if stock_id: stock = Stock.query.get_or_404(stock_id) res.data = stock.full_dict() else: res.data = [ s.full_dict() for s in Stock.query.filter_by( user_id=get_jwt_identity()).all() ] elif request.method == 'POST': body = should_look_like(stock_schema) stock = Stock(user_id=get_jwt_identity(), **body) stock.save() res.status = 201 elif request.method == 'PUT': body = should_look_like(stock_schema) stock.update_name(body['name']) stock.save() res.status = 201 elif request.method == 'DELETE': stock = Stock.query.get_or_404(stock_id) stock.delete() except HTTPException as exc: return exc except BaseException as exc: print(exc) abort(500) return res
def packaging_state(packaging_state_id=''): res = ApiResponse() try: if request.method == 'GET': res.data = [x for x in PackagingState.query.all()] elif request.method == 'POST': body = should_look_like(packaging_kind_schema) packaging_state = PackagingState(**body) packaging_state.save() res.status = 201 elif request.method == 'PUT': body = should_look_like(packaging_state_schema) packaging_state = PackagingState.query.get_or_404( packaging_state_id) packaging_state.update_name(body['name']) packaging_state.save() elif request.method == 'DELETE': packaging_state = PackagingState.query.get_or_404( packaging_state_id) packaging_state.delete() except HTTPException as exc: return exc except BaseException as exc: abort(500) return res
def user_session(): res = ApiResponse() id_token = request.cookies.get('id_token') if id_token: res.data = id_token return res abort(403)
def login(): res = ApiResponse() try: body = should_look_like(user_credentials_schema) app_user = AppUser.get_by_email(body['email']) if app_user and pbkdf2_sha256.verify(body['password'], app_user.pw_hash): res.data = { 'refresh_token': create_refresh_token(identity=app_user.id, expires_delta=timedelta(days=1)), 'access_token': create_access_token(identity=app_user.id, user_claims={'email': app_user.email}, expires_delta=timedelta(hours=1)), } res.status = 200 else: res.status = 401 res.pub_msg = 'Email or password was not recognized' except HTTPException as exc: return exc except BaseException as exc: abort(500) return res
def get_tags(): res = ApiResponse() db = get_db() res.data = [ dict(row) for row in db.execute('SELECT * FROM tag').fetchall() ] return res
def get_units_of_measure(): res = ApiResponse() try: res.data = UnitOfMeasurement.query.all() except HTTPException as exc: return exc except BaseException as exc: print(exc) abort(500) return res
def logout_refresh(): res = ApiResponse() try: revoked_token = RevokedToken(jti=get_raw_jwt()['jti']) revoked_token.save() except HTTPException as exc: return exc except BaseException as exc: abort(500) return res
def refresh_access(): res = ApiResponse() try: app_user = AppUser.query.get(get_jwt_identity()) res.data = create_access_token(identity=app_user.id, user_claims={'email': app_user.email}, expires_delta=timedelta(hours=1)) except HTTPException as exc: return exc except: abort(500) return res
def recipes(): res = ApiResponse() try: db = get_db() query = db.execute('SELECT * FROM recipe') res.data = [dict(row) for row in query.fetchall()] return res except BaseException as e: res.status = 500 if current_app.config['ENV'] == 'development': res.message = str(e) return res
def food_item_state(): res = ApiResponse() try: body = should_look_like(food_item_state_schema) food_item_state = StockItemState(**body) food_item_state.save() res.status = 201 except HTTPException as exc: return exc except BaseException as exc: print(exc) abort(500) return res
def register(): res = ApiResponse() try: body = should_look_like(user_credentials_schema) if AppUser.get_by_email(body['email']): res.status = 400 res.pub_msg = 'Email {} already exists in our system'.format( body['email']) else: pw_hash = pbkdf2_sha256.hash(body['password']) AppUser(email=body['email'], pw_hash=pw_hash).save() res.status = 201 except HTTPException as exc: return exc except BaseException as exc: print('EXCEPTION', exc) abort(500) return res
def food_kind(kind_id=''): res = ApiResponse() try: if request.method == 'GET': if kind_id: res.data = FoodKind.query.get_or_404(kind_id).full_dict() else: res.data = [ x.full_dict() for x in FoodKind.query.filter_by( user_id=get_jwt_identity()).all() ] elif request.method == 'POST': body = should_look_like(food_kind_schema) food_kind = FoodKind(**body) food_kind.user_id = get_jwt_identity() food_kind.save() res.status = 201 elif request.method == 'PUT': body = should_look_like(food_kind_schema) food_kind = FoodKind.query.get_or_404(kind_id) if str(food_kind.user_id) != get_jwt_identity(): res.status = 401 res.pub_msg = 'You do not have permission to update this "food kind"' else: food_kind.update_name(body['name']) food_kind.unit_of_measurement_id = body[ 'unit_of_measurement_id'] food_kind.serving_size = body['serving_size'] print(food_kind.unit_of_measurement_id) food_kind.save() elif request.method == 'DELETE': msg, status = helpers.delete_food_kind(kind_id=kind_id, user_id=get_jwt_identity(), force=request.args.get( 'force', False)) res.pub_msg = msg res.status = status except HTTPException as exc: print(str(exc)) return exc except BaseException as exc: print(exc) abort(500) return res
def tag(id=None): body = request.get_json() res = ApiResponse() try: db = get_db() if request.method == 'GET': query = '''SELECT * FROM recipe JOIN recipe_tag ON recipe.id = recipe_tag.recipe_id WHERE recipe_tag.tag_id = ?''' res.data = [ dict(row) for row in db.execute(query, [id]).fetchall() ] return res elif request.method == 'POST': try: query = 'INSERT INTO tag (id, name) VALUES (?, ?)' db.execute(query, [uuid.uuid4().hex, body['name']]) db.commit() res.status = 201 except BaseException as e: msg = str(e) if msg.startswith('UNIQUE constraint failed'): res.status = 200 else: res.status = 500 return res elif request.method == 'PUT': pass elif request.method == 'DELETE': pass except BaseException as e: res.status = 500 if current_app.config['ENV'] == 'development': res.message = str(e) return res
def create_snapshot(): res = ApiResponse() try: body = should_look_like(snapshot_schema) stock = Stock.query.get_or_404(body['stock_id']) if stock.user_id == get_jwt_identity(): snapshot = Snapshot(**body) for food_item in stock.stock_items: state = food_item.states.order_by( desc(StockItemState.date_created)).first() snapshot.food_item_states.append(state) snapshot.save() res.status = 201 else: res.status = 401 res.pub_msg = 'You do not have permission to create a snapshot of this stock' except HTTPException as exc: return exc except BaseException as exc: abort(500) return res
def reset_password(): res = ApiResponse() try: body = should_look_like(pw_reset_schema) nonce = get_jwt_identity() pw_reset_email = PwResetEmail.query.get(nonce) if pw_reset_email: app_user = AppUser.query.get(pw_reset_email.user_id) app_user.pw_hash = pbkdf2_sha256.hash(body['password']) app_user.save() pw_reset_email.delete() res.status = 200 else: res.status = 400 res.pub_msg = 'This link has expired.' except HTTPException as exc: print(exc) return exc except BaseException as exc: print(exc) abort(500) return res
def stock_item(stock_id='', item_id=''): res = ApiResponse() try: if request.method == 'POST': body = should_look_like(food_item_schema) stock = Stock.query.get_or_404(stock_id) if str(stock.user_id) == get_jwt_identity(): food_item = StockItem(**{'stock_id': stock_id, **body}) food_item.save() res.status = 201 else: res.status = 401 res.pub_msg = 'You do not have permission to add items to this stock' elif request.method == 'DELETE': food_item = StockItem.query.get_or_404(item_id) food_item.delete() except HTTPException as exc: return exc except BaseException as exc: print('EXCEPTION', exc) abort(500) return res
def send_reset_link(): res = ApiResponse() try: body = should_look_like(send_reset_link_schema) app_user = AppUser.get_by_email(body['email']) if app_user: # delete all records of previously sent pw reset emails so that # there will only be one valid link --- mitigate possibility of # pw reset link falling into the wrong hands for prev_email in PwResetEmail.find_by_user_id(app_user.id): prev_email.delete() # create new pw_reset_email record pw_reset_email = PwResetEmail(user_id=app_user.id) pw_reset_email.save() fresh_jwt = create_access_token( pw_reset_email.nonce, fresh=True, user_claims={'email': body['email']}, expires_delta=timedelta(minutes=30)) client_host = os.getenv('CLIENT_HOST') nonced_link = client_host + '/login/recover/' + fresh_jwt mail.send_message(subject='Grocery Inventory Password Reset', recipients=[body['email']], html=render_template('password_reset_email.html', nonced_link=nonced_link)) res.status = 201 res.pub_msg = 'If the email address you provided us is in our system you should recieve an email with a link to reset your password.' except HTTPException as exc: print(exc) return exc except BaseException as exc: print(exc) abort(500) return res
def food_category(category_id=''): res = ApiResponse() try: if request.method == 'GET': res.data = [cat for cat in FoodCategory.query.all()] elif request.method == 'POST': body = should_look_like(food_category_schema) cat = FoodCategory(**body) cat.save() res.status = 201 elif request.method == 'PUT': body = should_look_like(food_category_schema) cat = FoodCategory.query.get_or_404(category_id) cat.update_name(body['name']) cat.save() elif request.method == 'DELETE': cat = FoodCategory.query.get_or_404(category_id) cat.delete() except HTTPException as exc: return exc except BaseException as exc: abort(500) return res
def login(): body = should_look_like({ 'username': str, 'password': str, }) user = RegisteredUser.find_by_username(body['username']) if user and pbkdf2_sha256.verify(body['password'], user.pw_hash): user_profile = UserProfile.query.get(user.id) id_token = make_token(user.id, user_profile, expires_hours=1) res = ApiResponse() res.set_cookie('id_token', id_token, httponly=True, secure=True) res.status = 201 return res abort(403)
def register(): res = ApiResponse() body = should_look_like({ 'username': str, 'password': str, }) if not RegisteredUser.find_by_username(body['username']): pw_hash = pbkdf2_sha256.hash(body['password']) new_user = RegisteredUser(username=body['username'], pw_hash=pw_hash) new_user.save_to_db() user_profile = UserProfile(user_id=new_user.id, username=new_user.username, role_id=1) user_profile.save_to_db() id_token = make_token(new_user.id, user_profile, expires_hours=1) res.set_cookie('id_token', id_token, httponly=True, secure=True) res.status = 201 return res res.message = 'Username: "******" has already been taken'.format( body['username']) res.status = 400 return res
def create_error_api_response(error): res = ApiResponse() res.status = error.code if isinstance(error, HTTPException) else 500 res.pvt_msg = str(error) return res
def recipe(id=''): res = ApiResponse() try: db = get_db() if request.method == 'GET': sql = 'SELECT * FROM recipe WHERE id = ?' res.data = db.execute(sql, (id, )).fetchone() return res elif request.method == 'POST': body = request.get_json() id = uuid.uuid4().hex date_created = datetime.utcnow() title = body.get('title') unique_title = body.get('unique_title') description = body.get('description') markdown = body.get('markdown') html = body.get('html') query1 = db.execute('SELECT * FROM recipe WHERE unique_title = ?', [unique_title]) exists = query1.fetchone() if exists: res.message = 'There is already a recipe called "{}". Please choose another title'.format( title) res.status = 400 return res else: query2 = '''INSERT INTO recipe ( id, date_created, title, unique_title, description, markdown, html ) VALUES (?,?,?,?,?,?,?) ''' db.execute(query2, (id, date_created, title, unique_title, description, markdown, html)) db.commit() res.data = dict(id=id, date_created=date_created) res.status = 201 return res elif request.method == 'PUT': body = request.get_json() title = body.get('title') unique_title = body.get('unique_title') description = body.get('description') markdown = body.get('markdown') html = body.get('html') query1 = db.execute( 'SELECT * FROM recipe WHERE unique_title = ? AND id != ?', [unique_title, id]) exists = query1.fetchone() if exists: res.message = 'There is already a recipe called "{}". Please choose another title'.format( title) res.status = 400 return res else: query2 = ''' UPDATE recipe SET date_updated=:date_updated, title=:title, unique_title=:unique_title, description=:description, markdown=:markdown, html=:html WHERE id=:id''' db.execute( query2, { 'date_updated': datetime.utcnow(), 'title': title, 'unique_title': unique_title, 'description': description, 'markdown': markdown, 'html': html, 'id': id, }) db.commit() return res elif request.method == 'DELETE': db.execute('DELETE FROM recipe WHERE id=?', (id, )) db.commit() return res except BaseException as e: res.status = 500 if current_app.config['ENV'] == 'development': res.message = str(e) return res