def qr_codes_by_con_id(con_id): if bool(DoesContractHaveQRCode().execute_n_fetchone( {'con_id': con_id}, schema_out=False)['qr_code_claimable']): qr_codes = GetAllQRCodes().execute_n_fetchall({'con_id': con_id}) return success_response( {'qr_codes': [q['qr_code_location'] for q in qr_codes]}) else: return success_response({"qr_codes": []})
def post(self, data): # Get needed issuer, and contract data. collector = GetCollectorByCID().execute_n_fetchone( {'c_id': g.collector_info['c_id']}) contract = GetContractByConID().execute_n_fetchone( {'con_id': data['con_id']}, schema_out=False) try: g.geth.perform_transfer(contract['con_addr'], contract['con_abi'], data['t_id'], src_acct=collector['c_hash'], dest_acct=data['destination_wallet_hash']) UpdateTokenStatus().execute({ 'new_status': TokenStatus.EXTERNAL.value, 'this_id': data['t_id'] }) g.sesh.commit() except Exception as e: g.sesh.rollback() log_kv(LOG_ERROR, { 'error': str(e), 'message': "Could not perform external token transfer!" }, exception=True) return error_response( 'Unable to perform transfer. Please check the given wallet address', status_code=423) return success_response("Went through.")
def get(version=None): # Get all tr_ids of active trade_requests containing the authorized collector.. tr_ids = GetActiveTradeRequests(version).execute_n_fetchall({'c_id': g.collector_info['c_id']}, schema_out=False) trades = [] for tr_id in map(lambda x: x['tr_id'], tr_ids): # Get base trade info and all trade items associated. trade = GetTradeByTRID().execute_n_fetchone({'tr_id': tr_id}, schema_out=False) trade_items = GetTradeItems().execute_n_fetchall({'tr_id': tr_id}, schema_out=False) # Getting collector info.. trader_collector = GetCollectorByCID().execute_n_fetchone({'c_id': trade['trader_c_id']}) tradee_collector = GetCollectorByCID().execute_n_fetchone({'c_id': trade['tradee_c_id']}) # Getting trade offer, tradee offer info. trader_offers = [ GetTokenInfo().execute_n_fetchone({'con_id': t_i['con_id'], 't_id': t_i['t_id']}) for t_i in trade_items if t_i['owner'] == trade['trader_c_id'] ] tradee_offers = [ GetTokenInfo().execute_n_fetchone({'con_id': t_i['con_id'], 't_id': t_i['t_id']}) for t_i in trade_items if t_i['owner'] == trade['tradee_c_id'] ] # Setting them up in an object. cur_trade = TradeResponse().load({ 'trader': {'collector': trader_collector, 'eth_offer': trade['trader_eth_offer'], 'offers': trader_offers}, 'tradee': {'collector': tradee_collector, 'eth_offer': trade['tradee_eth_offer'], 'offers': tradee_offers}, 'status': trade['status'], 'tr_id': tr_id }) trades.append(cur_trade) return success_response({'trades': trades})
def get_issuer_jwt(data): # Gather up login details. login_deets = GetIssuerLoginDetails().execute_n_fetchone( binds=data, close_connection=True) if login_deets is None: log_kv( LOG_WARNING, { 'warning': 'could not find login details for issuer', 'username': data['username'] }) return error_response("Authorization Failed for Issuer Login.") # If we got some deets back then check if passwords match. if data['password'] == login_deets['password']: del login_deets['password'] log_kv(LOG_DEBUG, { 'debug': 'successfully logged in issuer', 'username': data['username'] }) return success_response({'jwt': generate_jwt(login_deets)}) else: log_kv( LOG_INFO, { 'message': 'authorization failed for issuer', 'username': data['username'] }) return error_response("Authorization Failed for Issuer Login.")
def delete(self, data): # Get trade specified by requester. trade = GetTradeByTRID().execute_n_fetchone(data, schema_out=False) # Make sure got a trade. if trade is None: return error_response('No trade request specified for that tr_id.') # Make sure trade is in correct state to delete. if trade['status'] != TradeStatus.REQUESTED.value: return error_response('Trade is not in a valid state to delete.') # Ensure requester has access to cancel this trade. if trade['trader_c_id'] != g.collector_info['c_id']: log_kv(LOG_INFO, {'info': "Attempted deletion of trade request not owned by authorized collector", 'c_id': g.collector_info['c_id']}) return error_response('Authorized collector does not have ownership over this trade.') # If identity has be verified update the status. data.update({'new_status': TradeStatus.CANCELED.value}) if UpdateTradeStatus().execute(data): g.sesh.commit() return success_response(status='Trade request canceled.') else: g.sesh.rollback() return error_response(status='Unable to cancel trade request.')
def post(self, data): try: data['i_hash'], data['i_priv_key'] = g.geth.create_account() issuer = create_issuer(data) g.sesh.commit() log_kv(LOG_INFO, {'message': 'successfully created issuer account'}) return success_response({'jwt': generate_jwt(issuer)}, http_code=201) except GethException as ge: g.sesh.rollback() log_kv( LOG_ERROR, { 'error': 'raised exception from geth_keeper while creating issuer account', 'exception': ge.exception, 'exc_message': ge.message }) return error_response(ge.message) except Exception as err: g.sesh.rollback() log_kv( LOG_ERROR, { 'error': 'an exception occurred while creating issuer account', 'exception': str(err) }) return error_response("Couldn't create issuer", http_code=200)
def get(self): """ Method to use for get requests to the /contract method. :return: """ contracts = GetContractsByIssuerID().execute_n_fetchall( {'i_id': g.issuer_info['i_id']}) if contracts is not None: log_kv( LOG_INFO, { 'message': 'succesfully retrieved issuer\'s contracts', 'issuer_id': g.issuer_info['i_id'] }) # Add the constraints to the contract object. for contract in contracts: contract.update( {'constraints': get_all_constraints(contract['con_id'])}) return success_response({'contracts': contracts}) else: log_kv( LOG_WARNING, { 'warning': 'could not get contract for issuer', 'issuer_id': g.issuer_info['i_id'] }) return error_response( status="Couldn't retrieve contract with that con_id", status_code=-1, http_code=200)
def get(self): collector = GetCollectorByCID().execute_n_fetchone( {'c_id': g.collector_info['c_id']}, close_connection=True) if collector: # Try and get out the eth balance. try: balance = g.geth.get_eth_balance(collector['c_hash']) except GethException as e: log_kv(LOG_ERROR, { 'error': "Couldn't retrieve eth balance", 'c_id': g.collector_info['c_id'], 'exception': e.exception, 'geth_message': e.message }, exception=True) balance = 'Not available at this time.' collector.update({'eth_balance': balance}) return success_response(collector) else: log_kv( LOG_WARNING, { 'warning': 'could not get collector account', 'collector_id': g.collector_info['c_id'] }) return error_response(status="Couldn't retrieve collector info.", status_code=-1, http_code=200)
def get_all_tradable(keyword=None): contracts = GetAllTradableContracts(keyword).execute_n_fetchall({}, close_connection=True, load_out=True) if contracts is not None: log_kv(LOG_DEBUG, {'debug': 'succesfully got all contracts'}) return success_response({'contracts': contracts}) else: log_kv(LOG_ERROR, {'warning': 'could not pull all contracts!!!'}) return error_response(status="Couldn't retrieve contracts")
def delete_customer(id): try: customer = Customer.query.get(id) if not customer: return jsonify(error_response("Customer doesn't exist")) db.session.delete(customer) db.session.commit() return jsonify(success_response('Successfully Deleted.')) except: return jsonify(error_response('Something went wrong'))
def claims(data): results, msg, err_code = claim_token_for_user( data['con_id'], g.collector_info['c_id'], data['location']['latitude'], data['location']['longitude'], data.get('constraints', {}), g.sesh) if results: g.sesh.commit() return success_response(msg) else: g.sesh.rollback() return error_response(msg, status_code=err_code)
def claim_by_qr_code(data): results, msg, err_code = claim_qr_code(data['con_id'], data['t_id'], g.collector_info['c_id'], data['location']['latitude'], data['location']['longitude']) if results: g.sesh.commit() return success_response(msg) else: g.sesh.rollback() return error_response(msg, status_code=err_code)
def get_collection(): # Get collection for user. collection = GetCollection().execute_n_fetchall( {'c_id': g.collector_info['c_id']}, close_connection=True) if collection is not None: return success_response({'collection': collection}) else: log_kv( LOG_ERROR, { 'error': 'could not get a user\'s collection', 'collector_id': g.collector_info['c_id'] }) return error_response("Couldn't retrieve collectors collection.")
def post(self, data): try: # If the user already exists, return a jwt to them collector = GetCollectorByUsername().execute_n_fetchone( {'username': data['username']}) if collector: log_kv( LOG_INFO, { 'message': 'the given user already exists', 'username': data['username'] }) return success_response({'jwt': generate_jwt(collector)}, http_code=201) # Create the collector account and bind the hash and private key data['c_hash'], data['c_priv_key'] = g.geth.create_account() collector = create_collector(data) g.sesh.commit() log_kv(LOG_INFO, {'message': 'successfully created collector'}) return success_response({'jwt': generate_jwt(collector)}, http_code=201) except GethException as ge: log_kv( LOG_ERROR, { 'error': 'a geth_exception occurred while creating collector account', 'exception': ge.exception, 'exc_message': ge.message }) return error_response(ge.message) except Exception as e: log_kv( LOG_ERROR, { 'error': 'an exception occurred while creating collector account', 'exception': str(e) }) return error_response(str(e), http_code=200)
def qr_codes_by_con_id_zip(con_id): qr_code_dir = get_qr_code_root_dir(con_id) qr_code_files = glob.glob(qr_code_dir) if len(qr_code_files) == 0: return success_response("No QR CODES associated with con_id.") save_location = get_qr_code_zip_dir(con_id) with ZipFile(save_location, 'w') as zip_file: for f in qr_code_files: zip_file.write(f, os.path.basename(f)) return serve_file(str(con_id) + '.zip', Folders.QR_CODES.value)
def decorator(*args, **kwargs): token = None if 'Authorization' in request.headers or 'x-access-token' in request.headers or 'token' in request.json: token = request.headers.get( 'x-access-token', None) or request.json.get( 'token', None) or request.headers.get('Authorization') token = token.replace('Bearer ', '') else: return jsonify(error_response('Token required')) try: decoded = jwt.decode(token, app.config['JWT_SECRET']) user = User.query.filter_by(id=decoded['id']).first() if not user: return jsonify(success_response('Invalid User')) except: return jsonify(error_response('Invalid Token')) return f(*args, **kwargs)
def analytics(con_id): # Get contract. data = g.sesh.execute( """ select num_created, qr_code_claimable from contracts where contracts.con_id = :contract_id;""", { "contract_id": con_id }).fetchall() # Check that the data is there if len(data) == 0: return error_response("Con id doesn't exist") num_created = data[0]['num_created'] qr_code_claimable = data[0]['qr_code_claimable'] # Figure out how many have been claimed. d_num_claimed = g.sesh.execute( """select count(*) as count1 from tokens where tokens.con_id=:contract_id and status='S';""", { 'contract_id': con_id }).fetchall() num_claimed = d_num_claimed[0]['count1'] if qr_code_claimable: constraints = None else: constraints = get_all_constraints(con_id) return success_response({ 'num_claimed': num_claimed, 'num_unclaimed': num_created - num_claimed, 'num_created': num_created, 'coordinates': claimed_coordinates(con_id), 'loc_constraints': loc_constraints(con_id), 'time_windows': token_time_windows(con_id), 'qr_code_claimable': qr_code_claimable, 'constraints': constraints, 'price_and_time': price_and_timestamps(con_id), 'traded': num_trades(con_id), 'num_traded_tokens': num_traded_tokens(con_id) })
def get_collector_by_username(username): collector = GetCollectorByUsername().execute_n_fetchone( {'username': username}, close_connection=True) if collector: log_kv(LOG_INFO, { 'message': 'successfully created collector', 'username': username }) return success_response(collector) else: log_kv(LOG_WARNING, { 'warning': 'could not create collector', 'username': username }) return error_response( status="Couldn't retrieve collector with that username", status_code=-1, http_code=200)
def get_contract_by_name(name): contracts_by_name = GetContractByName().execute_n_fetchall( {'name': '%' + name + '%'}, close_connection=True) if contracts_by_name is not None: log_kv(LOG_DEBUG, { 'debug': 'found contract by name', 'contract_name': name }) return success_response({'contracts': contracts_by_name}) else: log_kv(LOG_WARNING, { 'warning': 'could not find contract by name', 'contract_name': name }) return error_response( status="Couldn't retrieve contract with that con_id", status_code=-1, http_code=200)
def get_contract_by_con_id(con_id): contract = GetContractByConID().execute_n_fetchone({'con_id': con_id}) constraints = get_all_constraints(con_id) g.sesh.close() if contract: log_kv(LOG_DEBUG, { 'debug': 'successfully retrieved contract', 'contract_id': con_id }) contract.update({'constraints': constraints}) return success_response({'contract': contract}) else: log_kv(LOG_WARNING, { 'warning': 'could not find contract', 'contract_id': con_id }) return error_response( status="Couldn't retrieve contract with that con_id", status_code=-1, http_code=200)
def get_issuer_by_username(username): """ This method retrieves issuer data for the given username. :param username: username of issuer to retrieve. :return: """ issuer = GetIssuerByUsername().execute_n_fetchone({'username': username}, close_connection=True) if issuer: log_kv(LOG_INFO, { 'message': 'Successfully found issuer', 'issuer_username': username }) return success_response(issuer) else: log_kv(LOG_WARNING, { 'warning': 'Could not find account', 'issuer_username': username }) return error_response( status="Couldn't retrieve issuer with that username", status_code=-1, http_code=200)
def issuer_a_ping(): log_kv(LOG_INFO, {'message': 'authorized issuer ping called', 'issuer_id': g.issuer_info['i_id']}) return success_response("pong for i_id:{}".format(g.issuer_info['i_id']))
def post(self, data): try: # Ensure the trader is the one making the request. if data['trader']['c_id'] != g.collector_info['c_id']: return error_response('Not allowed to issue this trade request.') # Ensure all the items put up for trade are tradable tokens. con_ids = set([t_i['con_id'] for t_i in data['trader']['offers']] + [t_i['con_id'] for t_i in data['tradee']['offers']]) untradable_con_ids = GetUntradables(con_ids).execute_n_fetchall({}, schema_out=False) if len(untradable_con_ids) != 0: return error_response('Attempting to issue trade request with untradable tokens.', untradable_cons=untradable_con_ids, status_code=42) # Ensure trader owns all tokens put up by trader. for t_i in data['trader']['offers']: if not check_trade_item_ownership(data['trader']['c_id'], t_i['con_id'], t_i['t_id']): log_kv(LOG_INFO, {'info': 'collector made trade request containing token they did not own.', 'trader_c_id': data['trader']['c_id'], 'con_id': t_i['con_id'], 't_id': t_i['t_id']}) return error_response("Collector making request doesn't have ownership of tokens within trade", status_code=67) # Ensure trader doesn't have any active trades containing put up tokens. for t_i in data['trader']['offers']: if check_active_trade_item(data['trader']['c_id'], t_i['con_id'], t_i['t_id']): log_kv(LOG_INFO, {'info': 'collector attempting to make trade on active token.', 'trader_c_id': data['trader']['c_id'], 'con_id': t_i['con_id'], 't_id': t_i['t_id']}) return error_response("Collector making request already has token in an active trade.", status_code=90) # Ensure tradee owns all tokens request for t_i in data['tradee']['offers']: if not check_trade_item_ownership(data['tradee']['c_id'], t_i['con_id'], t_i['t_id']): log_kv(LOG_INFO, {'info': 'collector made trade request containing token tradee did not own.', 'tradee_c_id': data['tradee']['c_id'], 'con_id': t_i['con_id'], 't_id': t_i['t_id']}) return error_response("Collector making request for token the tradee doesn't have ownership of.", status_code=91) # Ensures the trader has the appropriate amount of eth. if data['trader']['eth_offer']: trader_info = GetTraderInfo().execute_n_fetchone({'c_id': g.collector_info['c_id']}, schema_out=False) trader_acct = trader_info['address'] balance = g.geth.get_eth_balance(trader_acct) if balance <= data['trader']['eth_offer']: log_kv(LOG_INFO, {'info': "Trader {} does not have enough eth.".format(g.collector_info['c_id'])}) return error_response("Trader does not have enough for specified eth offer.", status_code=127) # If we are dealing with a valid trade request persist it within the database. new_tr_id = create_trade_request(data) data.update({'tr_id': new_tr_id}) g.sesh.commit() return success_response(resp_data={'trade_info': data}, status='Trade request sent.', http_code=201) except Exception as e: g.sesh.rollback() return error_response("Couldn't create trade request.".format(str(e)))
def post(self): """ Method to use for post requests to the /contract method. :return: HTTP response """ try: # Parse out the data from the contract request. data = ContractRequest().loads(request.form['json_data']) except ValidationError as er: return error_response('Validation Failed', errors=er.messages) # Check to ensure we are not over the max token limit. if data['num_created'] > MAX_TOKEN_LIMIT: log_kv( LOG_WARNING, { 'warning': 'issuer tried to create contract over limit', 'issuer_id': g.issuer_info['i_id'], 'num_tokens': data['num_created'] }) return error_response( "Could not create a token contract with that many individual token. Max is {}" .format(MAX_TOKEN_LIMIT), status_code=89) # Update the original data given after validation for contract creation binds. data.update({'i_id': g.issuer_info['i_id']}) # If we have an image save it. file_location = 'default.png' if 'token_image' in request.files: file_location = save_file(request.files['token_image'], Folders.CONTRACTS.value, g.issuer_info['i_id']) data.update({'pic_location': file_location}) # If meta data is persistent save it. if 'meta_json_data' in request.form: data['metadata_location'] = save_json_data( request.form['meta_json_data'], g.issuer_info['i_id']) else: img_location = "project-token.com/contract/image=" + data[ 'pic_location'] data['metadata_location'] = save_json_data( DEFAULT_JSON_METADATA.format(name=data['name'], description=data['description'], img_loc=img_location), g.issuer_info['i_id']) try: # Get the received constraints in array format for the smart contract code_constraints, date_constraints, loc_constraints = self.get_constraints( data) # Issue the contract on the ETH network issuer = GetIssuerInfo().execute_n_fetchone( binds={'i_id': g.issuer_info['i_id']}) # Ensure we retrieved an issuer. if issuer is None: return error_response('Failed to retrieve issuer specified.', status_code=45) data['con_tx'], data['con_abi'], data[ 'gas_price'] = g.geth.issue_contract( issuer['i_hash'], issuer_name=issuer['username'], name=data['name'], desc=data['description'], img_url=data['pic_location'], num_tokes=data['num_created'], code_reqs=code_constraints, date_reqs=date_constraints, loc_reqs=loc_constraints, tradable=data['tradable'], metadata_uri=data['metadata_location']) # Insert into the database con_id, t_ids = insert_bulk_tokens(data['num_created'], data, g.sesh) # It is either qr_codes or other contstraints it cannot be both. if data['qr_code_claimable']: # Get all tokens to associate qr code with. for t_id in t_ids: # Generate the data to place in qr code. json_data_dict = dumps({ 'con_id': con_id, 't_id': t_id, 'jwt': generate_jwt({ 'con_id': con_id, 't_id': t_id }) }) # Make qr_code and save it. qrc = qrcode.make(json_data_dict) saved_location = save_qrcode(qrc, con_id, t_id) # If we successfully saved the image persist it into database. if saved_location is None: log_kv(LOG_ERROR, {'error': 'failed to make qrcode.'}) else: UpdateQRCODE().execute({ 'qr_code_location': saved_location, 'con_id': con_id, 't_id': t_id }) elif 'constraints' in data: # If constraints were passed in we need to process them. process_constraints(data['constraints'], con_id) g.sesh.commit() log_kv( LOG_INFO, { 'message': 'succesfully issued contract!', 'issuer_id': g.issuer_info['i_id'] }) return success_response('Success in issuing token!', http_code=201) except GethException as e: g.sesh.rollback() log_kv(LOG_ERROR, { 'error': 'a geth_exception occurred while issuing contract', 'issuer_id': g.issuer_info['i_id'], 'exception': e.exception, 'exc_message': e.message }, exception=True) return error_response(e.message) except Exception as e: g.sesh.rollback() log_kv(LOG_ERROR, { 'error': 'an exception occurred while issuing contract', 'issuer_id': g.issuer_info['i_id'], 'exception': str(e) }, exception=True) return error_response( "Couldn't create new contract. Exception {}".format(str(e)))
def put(self, data): # Get trade specified by requester. trade = GetTradeByTRID().execute_n_fetchone(data, schema_out=False) # Make sure got a trade. if trade is None: return error_response('No trade request specified for given tr_id.') # Make sure trade is in correct state. if trade['status'] != TradeStatus.REQUESTED.value: return error_response('Trade is not in a valid state to accept.') # Ensure requester has access to respond to this request. if trade['tradee_c_id'] != g.collector_info['c_id']: log_kv(LOG_INFO, {'info': "Attempted manipulation of trade request not directed to authorized collector.", 'c_id': g.collector_info['c_id']}) return error_response('Authorized collector is not the collector trade was intended for.') # logic for accepting the request if data['accept']: # Get trade items specified by requester. trade_items = GetTradeItems().execute_n_fetchall({'tr_id': trade['tr_id']}, schema_out=False) # Check to make sure the trade_items are still valid. if is_valid_trade_items(trade_items): # If trade items are valid we can go through with the trade. Start by invalidating all trades # containing items used within this trade. for trade_item in trade_items: try: InvalidateTradeRequests().execute({'con_id': trade_item['con_id'], 't_id': trade_item['t_id']}) except Exception as e: log_kv(LOG_ERROR, {'error': 'error invalidating trades containing trade items', 'con_id': trade_item['con_id'], 't_id': trade_item['t_id'], 'exception': str(e)}, exception=True) g.sesh.rollback() return error_response('Error accepting request.', http_code=400) # Go through and transfer ownership over trader_c_id, tradee_c_id = trade['trader_c_id'], trade['tradee_c_id'] # Update trade request logic. data.update({'new_status': TradeStatus.WAITING.value}) if not UpdateTradeStatus().execute(data): g.sesh.rollback() return error_response(status='Error accepting request.') # Perform the logic on the block chain now. try: validate_offer_and_trade(trade_items, tradee_c_id, trader_c_id, trade['trader_eth_offer']) except GethException as e: log_kv(LOG_ERROR, {'error': 'exception while performing trades', 'exception': str(e.exception), 'message': e.message}, exception=True) g.sesh.rollback() # status code 69 is for not enough eth to make transfer. if e.exception_number == 69: return error_response(status_code=69, http_code=400) else: return error_response('Error accepting request. [G]') except Exception as e: log_kv(LOG_ERROR, {'error': 'exception while performing trades', 'exception': str(e)}, exception=True) g.sesh.rollback() return error_response('Error accepting request. [G]') # If all the ethereum logic went through then commit database changes. g.sesh.commit() return success_response(status='Trade request accepted.') else: # Perform logic to decline the trade. data.update({'new_status': TradeStatus.INVALID.value}) if UpdateTradeStatus().execute(data): g.sesh.commit() return success_response(status='Trade request declined.') else: g.sesh.rollback() return error_response(status='Unable to decline trade request.') # Logic for declining the request. else: # Perform logic to decline the trade. data.update({'new_status': TradeStatus.DECLINED.value}) if UpdateTradeStatus().execute(data): g.sesh.commit() return success_response(status='Trade request declined.') else: g.sesh.rollback() return error_response(status='Unable to decline trade request.')
def pings(): log_kv(LOG_INFO, {'message': 'ping called pong respond'}) return success_response("pong")
def collector_a_ping(): log_kv(LOG_INFO, {'message': 'authorized collector ping called', 'collector_id': g.collector_info['c_id']}) return success_response("pong for c_id:{}".format(g.collector_info['c_id']))