def get_resource_json(self, resource_id): """ Gets a resource or None as a JSON-compatible object Keyword arguments: resource_id -- the object id for a resource """ response = ActionResponse(action_name='get_resource') resource_or_none = self.get_resource_raw(resource_id=resource_id) if resource_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'resource not found for given identifier' }) return response.to_dict() response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'resource found', ReCon.KEY_ACTION_DATA_DATA_ITEM: resource_or_none.to_dict() if getattr( resource_or_none, 'to_dict', None) else resource_or_none.to_json() }) return response.to_dict()
def delete_resource(self, resource_id=None): """ Given an identifier, deletes a resource and returns a JSON-compatible response. ** Subclasses can override this method to add additional checks Keyword arguments: resource_id -- the object id for the resource """ response = ActionResponse(action_name='delete_resource') resource_or_none = self.get_resource_raw(resource_id=resource_id) if resource_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND) return response.to_dict() try: resource_or_none.delete() except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_DELETED) return response.to_dict()
def get_user_orders(self, user_id=None, page=0, ipp=10): """ Given a user id, gets orders for a user. Keyword arguments: user_id -- the user's object id page -- the page ipp -- the number of items returned per 'page' """ response = ActionResponse(action_name='get_orders_for_user') user_or_none = self.get_resource_raw(resource_id=user_id) if user_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND) return response.to_dict() if page < 0 or type(page) is not int: page = 0 if ipp < 10 or type(ipp) is not int: ipp = 10 try: orders = Orders.objects(assoc_user=user_or_none).skip(page * ipp).limit(ipp) total_items = Orders.objects(assoc_user=user_or_none).count() if total_items % ipp == 0: total_pages = int(total_items / ipp) else: total_pages = int(total_items / ipp) + 1 except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: if not total_items: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Query returned no results' }) return response.to_dict() response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Query returned a total of {num_res} result(s)'.format(num_res=total_items), ReCon.KEY_ACTION_DATA_TOTAL_PAGES: total_pages, ReCon.KEY_ACTION_DATA_TOTAL_ITEMS: total_items, ReCon.KEY_ACTION_DATA_PAGE: page, ReCon.KEY_ACTION_DATA_IPP: ipp, ReCon.KEY_ACTION_DATA_DATA_SET: [ o.to_dict() if getattr(o, 'to_dict', None) else o.to_json() for o in orders ] }) return response.to_dict()
def api_patch_order(order_id=None): # ?action=set_status {'order_status': 'in_progress'} if request.args.get(RoCon.PARAM_ACTION) == RoCon.PARAM_ACTION_SET_STATUS: return jsonify( orders_res.update_order_status(order_id=order_id, order_data=request.get_json(), user_obj=None)) response = ActionResponse(action_name='update_order') response.set_data(action_message='invalid_action') return jsonify(response.to_dict())
def update_order_status(self, order_id=None, order_data=None, user_obj=None): """ Updates an order's status Keyword arguments: order_id -- the object id for the order order_data -- a dictionary containing the order status user_obj -- the user responsible for making the update """ response = ActionResponse(action_name='update_order_status') order_or_none = self.get_resource_raw(resource_id=order_id) if order_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND) return response.to_dict() if not order_data or type(order_data) is not dict: response.set_data(action_message=ReCon.ERR_MISSING_JSON_OBJ) return response.to_dict() if MoCon.ORDERS_ORDER_STATUS not in order_data: response.set_data(action_message=ReCon.ERR_MISSING_JSON_KEY) return response.to_dict() # if not user_obj or type(user_obj) is not UserProfiles: # response.set_data(action_message=ReCon.ERR_MISSING_USER_OBJ) # return response.to_dict() order_or_none.order_status = order_data[MoCon.ORDERS_ORDER_STATUS] order_or_none.updated_at = datetime.datetime.now() # order_or_none.updated_by = user_obj try: order_or_none.save() except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_SAVED) return response.to_dict()
def update_resource(self, resource_id=None, resource_data=None): """ Given some data, updates a resource specified by an identifier. Keyword arguments: resource_id -- the object id for the resource resource_data -- dictionary containing data """ response = ActionResponse(action_name='update_resource') resource_or_none = self.get_resource_raw(resource_id=resource_id) if resource_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND) return response.to_dict() if not resource_data or type(resource_data) is not dict: response.set_data(action_message=ReCon.ERR_MISSING_JSON_OBJ) return response.to_dict() should_update = False for k, v in resource_data.items(): if hasattr(resource_or_none, 'k'): resource_or_none.k = v should_update = True if should_update: try: resource_or_none.save() except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_SAVED) return response.to_dict() else: response.set_data(action_message=ReCon.ERR_NOTHING_TO_UPDATE) return response.to_dict()
def get_item_and_related(self, item_id=None): """ Gets item and related Keyword arguments: item_id -- item object id """ response = ActionResponse(action_name='get_item_with_related') resource_or_none = self.get_resource_raw(resource_id=item_id) if resource_or_none is None: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND) return response.to_dict() response.action_result = True item_data = { ReCon.KEY_ACTION_DATA_DETAIL: 'item found', ReCon.KEY_ACTION_DATA_DATA_ITEM: resource_or_none.to_dict() if getattr(resource_or_none, 'to_dict', None) else resource_or_none.to_json() } try: related_items = CafeItems.objects( item_type=resource_or_none.item_type, id__ne=resource_or_none.id) except: related_items = [] item_data[ReCon.KEY_ACTION_DATA_RELATED_ITEMS] = [ r.to_dict() if getattr(r, 'to_dict', None) else r.to_json() for r in related_items ] response.set_data(action_message=ReCon.INFO_RESOURCE_FOUND, action_data=item_data) return response.to_dict()
def create_resource(self, resource_data=None): """ Given some data, creates a resource and returns a JSON-compatible response resource_data -- dictionary containing resource data """ response = ActionResponse(action_name='create_resource') if not resource_data: response.set_data(action_message=ReCon.ERR_MISSING_JSON_OBJ) return response.to_dict() if getattr(self.model_or_none, 'get_required_fields', None): for r_key in self.model_or_none.get_required_fields(): if r_key not in resource_data: response.set_data( action_message=ReCon.ERR_MISSING_JSON_KEY, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Missing JSON Key -> {json_key}'.format( json_key=r_key) }) return response.to_dict() resource = self.model_or_none(**resource_data) try: resource.save() except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: response.action_result = True response.set_data(action_message=ReCon.INFO_RESOURCE_SAVED) return response.to_dict()
def get_resources_json(self, page=0, ipp=10, query_doc=None): """ Gets a list of resources as a JSON-compatible object. Keyword arguments: page -- when used in conjunction with ipp (items per page) defines pagination ipp -- controls the maximum number of items returned per 'page' query_doc -- a dictionary to be used as a query document """ response = ActionResponse(action_name='get_resources') if page < 0 or type(page) is not int: page = 0 if ipp < 3 or type(ipp) is not int: ipp = 10 if not query_doc or type(query_doc) is not dict: query_doc = {} try: resources = self.model_or_none.objects(__raw__=query_doc).skip( page * ipp).limit(ipp) total_items = self.model_or_none.objects(__raw__=query_doc).count() if total_items % ipp == 0: total_pages = int(total_items / ipp) else: total_pages = int(total_items / ipp) + 1 except: response.set_data(action_message=ReCon.ERR_DATABASE_OPERATION, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: str(sys.exc_info()) }) return response.to_dict() else: if not total_items: response.set_data(action_message=ReCon.ERR_RESOURCE_NOT_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Query returned no results' }) return response.to_dict() response.action_result = True response.set_data( action_message=ReCon.INFO_RESOURCE_FOUND, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Query returned a total of {num_res} result(s)'.format( num_res=total_items), ReCon.KEY_ACTION_DATA_TOTAL_ITEMS: total_items, ReCon.KEY_ACTION_DATA_TOTAL_PAGES: total_pages, ReCon.KEY_ACTION_DATA_DATA_SET: [ r.to_dict() if getattr(r, 'to_dict', None) else r.to_json() for r in resources ], ReCon.KEY_ACTION_DATA_PAGE: page, ReCon.KEY_ACTION_DATA_IPP: ipp }) return response.to_dict()
def decorated(*args, **kwargs): auth = request.headers.get(RoCon.HTTP_HEADER_AUTH, None) response = ActionResponse(action_name='authenticate_api') if not auth: response.set_data(action_message=ReCon.ERR_AUTH_HEADER_MISSING, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Authentication header not presented' }) return authenticate(error=response.to_dict()) parts = auth.split() if parts[0].lower() != 'bearer': response.set_data(action_message=ReCon.ERR_AUTH_HEADER_INVALID, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Authentication header was invalid' }) return jsonify(response.to_dict()) elif len(parts) == 1: response.set_data(action_message=ReCon.ERR_AUTH_TOKEN_MISSING, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Authentication token is missing' }) return jsonify(response.to_dict()) elif len(parts) > 2: response.set_data(action_message=ReCon.ERR_AUTH_HEADER_INVALID, action_data={ ReCon.KEY_ACTION_DATA_DETAIL: 'Authentication header was invalid' }) return jsonify(response.to_dict()) token = parts[1] try: payload = jwt.decode( token, base64.b64decode( s=AUTH0_KEY.replace('_', '/').replace('-', '+')), audience=AUTH0_AUDIENCE) except jwt.ExpiredSignatureError: response.set_data(action_message=ReCon.ERR_AUTH_TOKEN_EXPIRED, action_data={ReCon.KEY_ACTION_DATA_DETAIL: ''}) return authenticate(error=response.to_dict()) except jwt.InvalidAudienceError: response.set_data(action_message=ReCon.ERR_AUTH_AUDIENCE_INVALID, action_data={ReCon.KEY_ACTION_DATA_DETAIL: ''}) return authenticate(error=response.to_dict()) except jwt.InvalidIssuedAtError: response.set_data(action_message=ReCon.ERR_AUTH_ISSUED_AT_INVALID, action_data={}) return authenticate(error=response.to_dict()) except jwt.DecodeError: response.set_data(action_message=ReCon.ERR_AUTH_DECODE_ERROR, action_data={}) return authenticate(error=response.to_dict()) _request_ctx_stack.top.current_user = payload _request_ctx_stack.top.current_user['session_jwt'] = token return f(*args, **kwargs)