Example #1
0
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': '*'})
Example #2
0
def generate_payment_request(crypto_addr, x509_cert, expires, signer=None, amount=0, memo=None, payment_url=None, merchant_data=None):

    # Setup & Populate PaymentDetails
    payment_details = PaymentDetails()

    # Setup Single PaymentDetails Output
    output = payment_details.outputs.add()
    output.amount = amount * 100000000 # BTC to Satoshis

    if crypto_addr[0] == '1':
        output.script = serialize_script([OP_DUP, OP_HASH160, b58check_to_hex(crypto_addr), OP_EQUALVERIFY, OP_CHECKSIG]).decode('hex')
    else:
        try:
            int(crypto_addr, 16)
            output.script = str(crypto_addr).decode('hex')
        except ValueError:
            output.script = str(crypto_addr)

    # Add current and expiration epoch time values
    payment_details.time = int(datetime.utcnow().strftime('%s'))

    payment_details.expires = expires

    # Handle Various Optional Fields in PaymentDetails
    payment_details.memo = memo if memo else ''
    payment_details.payment_url = payment_url if payment_url else ''
    payment_details.merchant_data = str(merchant_data) if merchant_data else ''

    # Setup & Populate PaymentRequest
    payment_request = PaymentRequest()
    payment_request.payment_details_version = 1
    payment_request.serialized_payment_details = payment_details.SerializeToString()

    # Set PKI Type / Data
    if not x509_cert or not signer:
        payment_request.pki_type = 'none'
        payment_request.pki_data = ''
    else:

        payment_request.pki_type = signer.get_pki_type()
        pki_data = X509Certificates()

        for cert in get_certs(x509_cert):
            pki_data.certificate.append(cert)

        payment_request.pki_data = pki_data.SerializeToString()

    # Sign PaymentRequest
    if signer and x509_cert:
        payment_request.signature = ''
        payment_request.signature = signer.sign(payment_request.SerializeToString())

    # Log Payment Request to Logging System
    logger = PluginManager.get_plugin('LOGGER', config.logger_type)
    logger.log_payment_request(crypto_addr, signer.__class__.__name__, amount, expires, memo, payment_url, merchant_data)

    log.debug('Generated Payment Request [Address: %s | Signer: %s | Amount: %s | Expires: %s | Memo: %s | Payment URL: %s | Merchant Data: %s]' %
              (crypto_addr, signer.__class__.__name__, amount, expires, memo, payment_url, merchant_data))

    return payment_request.SerializeToString()
Example #3
0
def get_unused_presigned_payment_request(id_obj):

    redis_conn = Redis.from_url(config.redis_addr_cache_uri)
    resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)

    return_pr = None
    used_pr = []

    if config.store_and_forward_only and id_obj.presigned_payment_requests:
        return_pr = id_obj.presigned_payment_requests[0]
        id_obj.presigned_payment_requests.remove(return_pr)
        resolver.save(id_obj)
        return return_pr

    for pr in id_obj.presigned_payment_requests:

        if any([redis_conn.get(x) for x in get_addrs_from_paymentrequest(pr.decode('hex'))]):
            used_pr.append(pr)
            continue

        return_pr = pr
        break

    for pr in used_pr:
        id_obj.presigned_payment_requests.remove(pr)

    if used_pr:
        resolver.save(id_obj)

    return return_pr
Example #4
0
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})
Example #5
0
    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)})
Example #6
0
    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)
Example #7
0
    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)})
Example #8
0
    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)
Example #9
0
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)
Example #10
0
    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)
            })
Example #11
0
def get_unused_bip32_address(id_obj):

    if not id_obj.master_public_key:
        raise ValueError('Master public key missing. Unable to generate bip32 address.')

    # Determine correct branch based on derive logic
    branch = derive_branch()

    # Get last generated index for the branch if it exists.
    lg_index = PluginManager.get_plugin('RESOLVER', config.resolver_type).get_lg_index(id_obj.id, branch)

    while True:
        wallet_addr = generate_bip32_address_from_extended_pubkey(id_obj.master_public_key, branch, lg_index)

        if not redis_conn.get(wallet_addr):
            log.info('New Wallet Address created [Address: %s | Branch: %s | GenIndex: %s]' % (wallet_addr, branch, lg_index))
            PluginManager.get_plugin('RESOLVER', config.resolver_type).set_lg_index(id_obj.id, branch, lg_index)
            return wallet_addr
        else:
            log.debug('Used Wallet Address found! Trying next index [Branch: %s | GenIndex: %s]' % (branch, lg_index))
            lg_index += 1
Example #12
0
    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)})
Example #13
0
    def tearDownClass(cls):

        time.sleep(1)

        resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        log.info('Clean Up Functest')

        log.info('Deleting All testid InvoiceRequests if any exist')
        for message_type in ProtocolMessageType.keys():
            resolver.delete_paymentprotocol_message(cls.identifier, message_type, id='testid')

        log.info('Deleting Test IdObj')
        resolver.delete(BIP75FunctionalTest.test_id_obj)
Example #14
0
    def tearDownClass(cls):

        time.sleep(1)

        resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        log.info('Clean Up Functest')

        log.info('Deleting All testid InvoiceRequests if any exist')
        for message_type in ProtocolMessageType.keys():
            resolver.delete_paymentprotocol_message(cls.identifier,
                                                    message_type,
                                                    id='testid')

        log.info('Deleting Test IdObj')
        resolver.delete(BIP75FunctionalTest.test_id_obj)
Example #15
0
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)
Example #16
0
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)
Example #17
0
    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)
            })
Example #18
0
    def setUpClass(cls):

        log.info('Generating ECDSA Keypairs for Testing')
        cls.sender_sk = SigningKey.generate(curve=curves.SECP256k1)
        cls.receiver_sk = SigningKey.generate(curve=curves.SECP256k1)

        log.info('Setup IdObj for testid')
        cls.test_id_obj = IdObject()
        cls.test_id_obj.auth_public_key = cls.receiver_sk.get_verifying_key().to_der().encode('hex')
        cls.test_id_obj.id = 'testid'
        cls.test_id_obj.paymentprotocol_only = True

        cls.resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        cls.resolver.save(cls.test_id_obj)
        log.info('Save testid IdObj')

        log.info('Setup Class Identifier')

        cls.identifier = None
Example #19
0
    def setUp(self):

        # Generate a signing key used for refund output retrieval in get_refund_addresses()
        self.receiver_sk = SigningKey.generate(curve=curves.SECP256k1)

        log.info('Setup IdObj for testid')
        self.test_id_obj = IdObject()
        self.test_id_obj.id = 'testid'
        self.test_id_obj.bip70_enabled = True
        self.test_id_obj.wallet_address = '1MSK1PMnDZN4SLDQ6gB4c6GKRExfGD6Gb3'
        self.test_id_obj.x509_cert = TEST_CERT
        self.test_id_obj.private_key = TEST_CERT_PRIVKEY
        self.test_id_obj.auth_public_key = self.receiver_sk.get_verifying_key().to_string().encode('hex')

        self.resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        self.resolver.save(self.test_id_obj)
        log.info('Save testid IdObj')

        # Keep track of PaymentRequest meta data stored in Redis so it can be cleaned up later
        self.redis_pr_store_cleanup = []
Example #20
0
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)
Example #21
0
    def setUpClass(cls):

        log.info('Generating ECDSA Keypairs for Testing')
        cls.sender_sk = SigningKey.generate(curve=curves.SECP256k1)
        cls.receiver_sk = SigningKey.generate(curve=curves.SECP256k1)

        log.info('Setup IdObj for testid')
        cls.test_id_obj = IdObject()
        cls.test_id_obj.auth_public_key = cls.receiver_sk.get_verifying_key(
        ).to_der().encode('hex')
        cls.test_id_obj.id = 'testid'
        cls.test_id_obj.paymentprotocol_only = True

        cls.resolver = PluginManager.get_plugin('RESOLVER',
                                                config.resolver_type)
        cls.resolver.save(cls.test_id_obj)
        log.info('Save testid IdObj')

        log.info('Setup Class Identifier')

        cls.identifier = None
Example #22
0
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)
Example #23
0
    def setUp(self):

        # Generate a signing key used for refund output retrieval in get_refund_addresses()
        self.receiver_sk = SigningKey.generate(curve=curves.SECP256k1)

        log.info('Setup IdObj for testid')
        self.test_id_obj = IdObject()
        self.test_id_obj.id = 'testid'
        self.test_id_obj.bip70_enabled = True
        self.test_id_obj.wallet_address = '1MSK1PMnDZN4SLDQ6gB4c6GKRExfGD6Gb3'
        self.test_id_obj.x509_cert = TEST_CERT
        self.test_id_obj.private_key = TEST_CERT_PRIVKEY
        self.test_id_obj.auth_public_key = self.receiver_sk.get_verifying_key(
        ).to_string().encode('hex')

        self.resolver = PluginManager.get_plugin('RESOLVER',
                                                 config.resolver_type)
        self.resolver.save(self.test_id_obj)
        log.info('Save testid IdObj')

        # Keep track of PaymentRequest meta data stored in Redis so it can be cleaned up later
        self.redis_pr_store_cleanup = []
Example #24
0
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)

    # Setup PaymentRequest
    pr = generate_payment_request(
        wallet_addr,
        id_obj.x509_cert,
        signer,
        amount,
        id_obj.expires,
        id_obj.memo,
        id_obj.payment_url,
        id_obj.merchant_data
    )

    return Response(response=pr, status=200, content_type=PR_MIMETYPE, headers={'Content-Transfer-Encoding': 'binary', 'Access-Control-Allow-Origin': '*'})
Example #25
0
def get_unused_presigned_payment_request(id_obj):

    redis_conn = Redis.from_url(config.redis_addr_cache_uri)

    return_pr = None
    used_pr = []

    for pr in id_obj.presigned_payment_requests:

        if any([redis_conn.get(x) for x in get_addrs_from_paymentrequest(pr.decode('hex'))]):
            used_pr.append(pr)
            continue

        return_pr = pr
        break

    for pr in used_pr:
        id_obj.presigned_payment_requests.remove(pr)

    if used_pr:
        resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        resolver.save(id_obj)

    return return_pr
Example #26
0
def generate_payment_request(crypto_addr, x509_cert, signer=None, amount=0, expires=None, memo=None, payment_url=None, merchant_data=None):

    # Setup & Populate PaymentDetails
    payment_details = PaymentDetails()

    # Setup Single PaymentDetails Output
    output = payment_details.outputs.add()
    output.amount = amount * 100000000 # BTC to Satoshis

    if crypto_addr[0] == '1':
        output.script = serialize_script([OP_DUP, OP_HASH160, b58check_to_hex(crypto_addr), OP_EQUALVERIFY, OP_CHECKSIG]).decode('hex')
    else:
        try:
            int(crypto_addr, 16)
            output.script = str(crypto_addr).decode('hex')
        except ValueError:
            output.script = str(crypto_addr)

    # Add current and expiration epoch time values
    payment_details.time = int(datetime.utcnow().strftime('%s'))

    if expires:
        if isinstance(expires, int) or isinstance(expires, long):
            payment_details.expires = int((datetime.utcnow() + timedelta(seconds=expires)).strftime('%s'))
        elif isinstance(expires, datetime.__class__):
            payment_details.expires = int(expires.strftime('%s'))
    else:
        payment_details.expires = int((datetime.utcnow() + timedelta(seconds=config.bip70_default_expiration)).strftime('%s'))

    # Handle Various Optional Fields in PaymentDetails
    payment_details.memo = memo if memo else ''
    payment_details.payment_url = payment_url if payment_url else ''
    payment_details.merchant_data = str(merchant_data) if merchant_data else ''

    # Setup & Populate PaymentRequest
    payment_request = PaymentRequest()
    payment_request.payment_details_version = 1
    payment_request.serialized_payment_details = payment_details.SerializeToString()

    # Set PKI Type / Data
    if not x509_cert or not signer:
        payment_request.pki_type = 'none'
        payment_request.pki_data = ''
    else:

        payment_request.pki_type = signer.get_pki_type()
        pki_data = X509Certificates()

        for cert in get_certs(x509_cert):
            pki_data.certificate.append(cert)

        payment_request.pki_data = pki_data.SerializeToString()

    # Sign PaymentRequest
    if signer and x509_cert:
        payment_request.signature = ''
        payment_request.signature = signer.sign(payment_request.SerializeToString())

    # Log Payment Request to Logging System
    logger = PluginManager.get_plugin('LOGGER', config.logger_type)
    logger.log_payment_request(crypto_addr, signer.__class__.__name__, amount, expires, memo, payment_url, merchant_data)

    log.debug('Generated Payment Request [Address: %s | Signer: %s | Amount: %s | Expires: %s | Memo: %s | Payment URL: %s | Merchant Data: %s]' %
              (crypto_addr, signer.__class__.__name__, amount, expires, memo, payment_url, merchant_data))

    return payment_request.SerializeToString()
Example #27
0
__author__ = 'frank'

from addressimo.config import config
from addressimo.plugin import PluginManager
from addressimo.util import LogUtil

log = LogUtil.setup_logging()

PluginManager.register_plugins()
resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)


log.info('Starting Stale PaymentRequest Meta Data Cleanup')
resolver.cleanup_stale_payment_request_meta_data()
log.info('Completed Stale PaymentRequest Meta Data Cleanup')


log.info('Starting Stale Payment Meta Data Cleanup')
resolver.cleanup_stale_payment_meta_data()
log.info('Completed Stale Payment Meta Data Cleanup')


log.info('Starting Stale InvoiceRequest Data Cleanup')
resolver.cleanup_stale_invoicerequest_data()
log.info('Completed Stale InvoiceRequest Data Cleanup')


log.info('Starting Stale EncryptedPaymentRequest Data Cleanup')
resolver.cleanup_stale_encrypted_paymentrequest_data()
log.info('Completed Stale EncryptedPaymentRequest Data Cleanup')
Example #28
0
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)
Example #29
0
# ###########################################
# Setup Pre-Request Processing
# ###########################################
@app.before_request
def before_request():

    # Handle our pre-flight OPTIONS check
    if request.method == 'OPTIONS':
        return create_json_response()


######################
# Register Plugins
######################
PluginManager.register_plugins()


# ###########################################
# Status Testing Route (for Load Balancing, etc)
@app.route('/index.html', methods=['GET', 'OPTIONS', 'HEAD', 'POST'])
def index():
    return Response("UP", status=200, mimetype='text/html')


@app.route('/api', defaults={'id': None}, methods=['GET'])
@app.route('/api/<id>', methods=['GET'])
def get_id_objs(id):
    return admin.get_id_objs(id)

Example #30
0
    @app.errorhandler(429)
    def ratelimit_handler(e):
        return create_json_response(success=False, message="ratelimit exceeded", status=429)

    @limiter.request_filter
    def ip_whitelist():
        return request.remote_addr == "127.0.0.1"

except ImportError:
    log.warn('Rate limiting not available. To add rate limiting, install the Flask-Limiter module, install Redis, and configure Redis in config.')

######################
# Register Plugins
######################
PluginManager.register_plugins()

# ###########################################
# Status Testing Route (for Load Balancing, etc)
@app.route('/index.html', methods=['GET', 'OPTIONS', 'HEAD', 'POST'])
def index():
    return Response("UP", status=200, mimetype='text/html')

@app.route('/time', methods=['GET'])
@limiter.limit("60 per minute")
def get_current_time():
    return create_json_response(
            message='current time in microseconds (utc)',
            data={'utime': int(time.time() * 1000 * 1000)}
    )
Example #31
0
    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})
Example #32
0
    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})