def update_id_obj(id): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) if not id: id_obj = IdObject() else: id_obj = resolver.get_id_obj(id) if not id_obj: return create_json_response(False, 'Object not found for this ID.', 404) rdata = request.get_json() if not set(rdata.keys()).issubset(id_obj.keys()): return create_json_response(False, 'Unknown key submitted', 400) for key, value in rdata.items(): if key == 'id': continue if key == 'private_key' and not value: continue id_obj[key] = value try: resolver.save(id_obj) except: return create_json_response(False, 'Exception occurred attempting to save id object', 500) return create_json_response(True, 'Update succeeded', 200, {'id': id_obj.id})
def get_count(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) return create_json_response(data={'payment_request_count': len(id_obj.presigned_payment_requests)})
def delete(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) resolver.delete(id_obj) return create_json_response(status=204)
def return_used_branches(id): if not config.admin_public_key: log.info('No key provided in config, Failing [ID: %s]' % id) return create_json_response(False, 'ID Not Recognized', 404) if request.headers.get('x-identity') == config.admin_public_key: return create_json_response(data={'branches': PluginManager.get_plugin('RESOLVER', config.resolver_type).get_branches(id)}) return create_json_response(False, 'ID Not Recognized', 404)
def get_count(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) return create_json_response( data={ 'payment_request_count': len(id_obj.presigned_payment_requests) })
def delete_id_obj(id): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(id) if not id_obj: return create_json_response(False, 'Object not found for this ID.', 404) try: resolver.delete(id_obj) except: return create_json_response(False, 'Exception occurred attempting to delete id object', 500) return create_json_response(True, 'Delete succeeded', 204)
def create_payment_request_response(wallet_addr, amount, id_obj): # TODO: This might not work with remote keys if not id_obj.x509_cert: raise ValueError('id_obj missing x509_cert') signer = PluginManager.get_plugin('SIGNER', config.signer_type) signer.set_id_obj(id_obj) if not id_obj.payment_url: log.info('Creating Addressimo payment_url [ID: %s]' % id_obj.id) resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) try: payment_url_uuid = resolver.set_payment_request_meta_data(id_obj.get_expires(), wallet_addr, amount * 100000000) except Exception: return create_json_response(False, 'Internal Server Error. Please try again.', 500) # Setup PaymentRequest pr = generate_payment_request( wallet_addr, id_obj.x509_cert, id_obj.get_expires(), signer, amount, id_obj.memo, id_obj.payment_url or 'https://%s/payment/%s' % (config.site_url, payment_url_uuid), id_obj.merchant_data if id_obj.payment_url else payment_url_uuid ) return Response(response=pr, status=200, content_type=PR_MIMETYPE, headers={'Content-Transfer-Encoding': 'binary', 'Access-Control-Allow-Origin': '*'})
def get_id_objs(id): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) if id: raw = resolver.get_id_obj(id) if not raw: return create_json_response(False, 'Object not found for this ID.', 404) raw['private_key'] = '' result = {'data': raw} else: result = {'keys': resolver.get_all_keys()} return create_json_response(True, '', 200, result)
def register(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = IdObject() id_obj.auth_public_key = request.headers.get('x-identity') resolver.save(id_obj) return create_json_response(data={'id': id_obj.id, 'endpoint': 'https://%s/resolve/%s' % (config.site_url, id_obj.id)})
def verify_public_key(): id = get_id() if not id: log.info('ID Unavailable from request: %s' % request.url) return create_json_response(False, 'Unknown Endpoint', 404) if not request.headers.get('x-identity'): log.info('No Pubkey Exists in Request, Returning False [ID: %s]' % id) return create_json_response(False, 'Missing x-identity header', 400) resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(id) if not id_obj: log.info('No Data Exists for Given ID, Failing [ID: %s]' % id) return create_json_response(False, 'ID Not Recognized', 404) if request.headers.get('x-identity') == id_obj.auth_public_key: return None return create_json_response(False, 'ID Not Recognized', 404)
def register(**kwargs): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = IdObject() id_obj.auth_public_key = request.headers.get('x-identity') for k,v in kwargs.items(): setattr(id_obj, k, v) resolver.save(id_obj) return create_json_response(data={'id': id_obj.id, 'endpoint': 'https://%s/address/%s/resolve' % (config.site_url, id_obj.id)})
def register(**kwargs): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = IdObject() id_obj.auth_public_key = request.headers.get('x-identity') for k, v in kwargs.items(): setattr(id_obj, k, v) resolver.save(id_obj) return create_json_response( data={ 'id': id_obj.id, 'endpoint': 'https://%s/address/%s/resolve' % (config.site_url, id_obj.id) })
def create_wallet_address_response(wallet_addr): return create_json_response(data={'wallet_address': wallet_addr})
def resolve(id): ################################### # Verify Resolver and Request Data ################################### if not config.store_and_forward_only and not cache_up_to_date(): log.critical('Address cache not up to date. Refresh Redis cache.') return create_json_response(False, 'Address cache not up to date. Please try again later.', 500) try: id_obj = PluginManager.get_plugin('RESOLVER', config.resolver_type).get_id_obj(id) except Exception as e: log.error('Exception retrieving id_obj [ID: %s | Exception: %s]' % (id, str(e))) return create_json_response(False, 'Exception occurred when retrieving id_obj from database', 500) if not id_obj: log.error('Unable to retrieve id_obj [ID: %s]' % id) return create_json_response(False, 'Unable to retrieve id_obj from database', 404) # Handle InvoiceRequests if id_obj.paymentprotocol_only: return create_json_response(False, 'Endpoint Requires a valid POST to create a PaymentRequest Request', 405, headers={'Allow': 'POST'}) # Handle Store & Forward-Only Mode if config.store_and_forward_only and not id_obj.presigned_payment_requests: return create_json_response(False, 'Endpoint Unavaiable, This is a Store & Forward ONLY Service', 404) ################################################################################# # Determine Wallet Address to Return or Use in BIP70 PaymentRequest Generation ################################################################################# if not id_obj.bip32_enabled and not id_obj.wallet_address: log.error('bip32_enabled is False and static wallet_address is missing [ID: %s]' % id) return create_json_response(False, 'Unable to retrieve wallet_address', 400) if id_obj.bip32_enabled: try: waddr = get_unused_bip32_address(id_obj) except Exception as e: log.error('Exception occurred retrieving unused bip32 address [EXCEPTION: %s | ID: %s]' % (str(e), id)) return create_json_response(False, 'Unable to retrieve wallet_address', 500) else: waddr = id_obj.wallet_address ########################### # Determine Response Type ########################### bip70_arg = request.args.get('bip70','').lower() # BIP70 Forced Request, but endpoint is not BIP70 capable if bip70_arg == 'true' and not id_obj.bip70_enabled: log.error('Required bip70_enabled value is missing or disabled [ID: %s | bip70_enabled: %s]' % (id, id_obj.get('bip70_enabled', None))) return create_json_response(False, 'Required bip70_enabled value is missing or disabled', 400) # BIP70-enabled Endpoint and BIP70 Request Forced or Accept-able by Client if id_obj.bip70_enabled and (bip70_arg == 'true' or PR_MIMETYPE in request.headers.get('accept')): # Handle Pre-signed PaymentRequests if id_obj.presigned_payment_requests: valid_pr = get_unused_presigned_payment_request(id_obj) if not valid_pr: return create_json_response(False, 'No PaymentRequests available for this ID', 404) return Response(response=valid_pr, status=200, content_type=PR_MIMETYPE, headers={'Content-Transfer-Encoding': 'binary', 'Access-Control-Allow-Origin': '*'}) elif id_obj.presigned_only: log.warn('Presigned PaymentRequests list empty [ID: %s]' % id) return create_json_response(False, 'No PaymentRequests available for this ID', 404) # Handle Non-Presigned PaymentRequests log.info('Creating bip70 payment request [ADDRESS: %s | AMOUNT: %s | ID: %s]' % (waddr, get_bip70_amount(id_obj), id)) try: return create_payment_request_response(waddr, get_bip70_amount(id_obj), id_obj) except Exception as e: log.error('Exception occurred creating payment request [EXCEPTION: %s | ID: %s]' % (str(e), id_obj.id)) return create_json_response(False, 'Unable to create payment request', 500) # BIP70-enabled Endpoint, but not BIP70-specific Request if id_obj.bip70_enabled and bip70_arg != 'false': # Handle Pre-signed Payment Requests if not id_obj.presigned_payment_requests and id_obj.presigned_only: log.warn('Presigned PaymentRequests list empty [ID: %s]' % id) return create_json_response(False, 'No PaymentRequests available for this ID', 404) elif id_obj.presigned_payment_requests: valid_pr = get_unused_presigned_payment_request(id_obj) if not valid_pr: return create_json_response(False, 'No PaymentRequests available for this ID', 404) return create_bip72_response(None, None, 'https://%s/address/%s/resolve?bip70=true' % (config.site_url, id)) # Handle Non-Presigned PaymentRequests log.info('Returning BIP72 URI [Address: %s | ID: %s]' % (waddr, id)) return create_bip72_response(waddr, get_bip70_amount(id_obj), 'https://%s/address/%s/resolve?bip70=true&amount=%s' % (config.site_url, id_obj.id, get_bip70_amount(id_obj))) # Return Standard BIP72 URI Response without a PaymentRequest URI log.info('Returning Wallet Address [Address: %s | ID: %s]' % (waddr, id)) return create_bip72_response(waddr, 0)
def ratelimit_handler(e): return create_json_response(success=False, message="ratelimit exceeded", status=429)
def get_current_time(): return create_json_response(message='current time in microseconds (utc)', data={'utime': int(time.time() * 1000 * 1000)})
def get_current_time(): return create_json_response( message='current time in microseconds (utc)', data={'utime': int(time.time() * 1000 * 1000)} )
def before_request(): # Handle our pre-flight OPTIONS check if request.method == 'OPTIONS': return create_json_response()
def add(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) rdata = None try: rdata = request.get_json() except Exception as e: log.warn("Exception Parsing JSON: %s" % str(e)) return create_json_response(False, 'Invalid Request', 400) if not rdata: return create_json_response(False, 'Invalid Request', 400) pr_list = rdata.get('presigned_payment_requests') if not pr_list: return create_json_response(False, 'Missing presigned_payment_requests data', 400) if not isinstance(pr_list, list): return create_json_response(False, 'presigned_payment_requests data must be a list', 400) # Validate PaymentRequests for pr in pr_list: try: int(pr, 16) except ValueError: return create_json_response(False, 'Payment Request Must Be Hex Encoded', 400) verify_pr = PaymentRequest() try: hex_decoded_pr = pr.decode('hex') if len(hex_decoded_pr) > PAYMENT_REQUEST_SIZE_MAX: log.warn('Rejecting Payment Request for Size [ACCEPTED: %d bytes | ACTUAL: %d bytes]' % (PAYMENT_REQUEST_SIZE_MAX, len(hex_decoded_pr))) return create_json_response(False, 'Invalid Payment Request Submitted', 400) verify_pr.ParseFromString(hex_decoded_pr) except Exception as e: log.warn('Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response(False, 'Invalid Payment Request Submitted', 400) verify_pd = PaymentDetails() try: verify_pd.ParseFromString(verify_pr.serialized_payment_details) except Exception as e: log.warn('Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response(False, 'Invalid Payment Request Submitted', 400) # Validated! add_count = 0 for pr in pr_list: id_obj.presigned_payment_requests.append(pr) add_count += 1 if add_count == config.presigned_pr_limit: log.info('Presigned Payment Limit Reached [ID: %s]' % id_obj.id) break log.info('Added %d Pre-Signed Payment Requests [ID: %s]' % (add_count, id_obj.id)) resolver.save(id_obj) return create_json_response(data={'payment_requests_added': add_count})
def add(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) rdata = None try: rdata = request.get_json() except Exception as e: log.warn("Exception Parsing JSON: %s" % str(e)) return create_json_response(False, 'Invalid Request', 400) if not rdata: return create_json_response(False, 'Invalid Request', 400) pr_list = rdata.get('presigned_payment_requests') if not pr_list: return create_json_response( False, 'Missing presigned_payment_requests data', 400) if not isinstance(pr_list, list): return create_json_response( False, 'presigned_payment_requests data must be a list', 400) # Validate PaymentRequests for pr in pr_list: try: int(pr, 16) except ValueError: return create_json_response( False, 'Payment Request Must Be Hex Encoded', 400) verify_pr = PaymentRequest() try: hex_decoded_pr = pr.decode('hex') if len(hex_decoded_pr) > PAYMENT_REQUEST_SIZE_MAX: log.warn( 'Rejecting Payment Request for Size [ACCEPTED: %d bytes | ACTUAL: %d bytes]' % (PAYMENT_REQUEST_SIZE_MAX, len(hex_decoded_pr))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) verify_pr.ParseFromString(hex_decoded_pr) except Exception as e: log.warn( 'Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) verify_pd = PaymentDetails() try: verify_pd.ParseFromString(verify_pr.serialized_payment_details) except Exception as e: log.warn( 'Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) # Validated! add_count = 0 for pr in pr_list: id_obj.presigned_payment_requests.append(pr) add_count += 1 if add_count == config.presigned_pr_limit: log.info('Presigned Payment Limit Reached [ID: %s]' % id_obj.id) break log.info('Added %d Pre-Signed Payment Requests [ID: %s]' % (add_count, id_obj.id)) resolver.save(id_obj) return create_json_response(data={'payment_requests_added': add_count})