Example #1
0
def test_dynamic_price(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                       client: Client, wait_for_blocks, receiver_privkey: str):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    price_cycle = cycle([1, 2, 3, 4, 5])
    url_to_price = {}

    def price_fn(url: str):
        if url in url_to_price:
            price = url_to_price[url]
        else:
            price = next(price_cycle)
            url_to_price[url] = price
        return price

    content = PaywalledContent(
        'resource_\d',
        price=price_fn,
        get_fn=lambda url: (url.split("_")[1], 200),
    )
    proxy.add_content(content)

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    response = requests.get(endpoint_url + '/resource_5')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 2

    response = requests.get(endpoint_url + '/resource_2')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    channel = client.get_suitable_channel(headers.receiver_address, 2)
    wait_for_blocks(6)
    channel.balance = 2

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource_5', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == '"5"'

    close_channel_cooperatively(channel, receiver_privkey,
                                client.channel_manager_address, 0)
Example #2
0
def test_get(empty_proxy: PaywalledProxy, api_endpoint_address: str,
             channel_manager_address: str, token_address: str,
             sender_address: str, receiver_address: str, client: Client,
             wait_for_blocks):
    """
    Test with manual client interaction for isolated server testing.
    Note: Debug in microraiden.proxy.resources.expensive for most of the server response logic.
    """
    es_mock = ElasticsearchBackend(None)
    es_mock.search = mock.Mock(return_value=Resource(
        price=5, content='success', expires_at=time.time() + 30))
    server = APIServer(empty_proxy, es=es_mock)
    api_path = 'http://' + api_endpoint_address

    # Request price (and cache resource).
    body = {'query': 'query something'}
    url = api_path + '/some_index/some_type/_search'
    response = requests.get(url, json=body)

    print(response.content)
    assert response.status_code == 402

    headers = HTTPHeaders.deserialize(response.headers)
    assert headers.token_address == token_address
    assert headers.contract_address == channel_manager_address
    assert headers.receiver_address == receiver_address
    price = int(headers.price)
    assert price == 5
    assert len(server.resource_cache) == 1

    # Perform payment and request same resource again. Include payment information in headers.
    channel = client.get_suitable_channel(receiver_address, price)
    # Server requires some confirmations, so mine some blocks.
    wait_for_blocks(10)
    channel.create_transfer(price)

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = sender_address
    headers.receiver_address = receiver_address
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(url, headers=headers, json=body)
    headers = HTTPHeaders.deserialize(response.headers)

    assert 'nonexisting_channel' not in headers, 'Server should acknowledge the created channel.'
    assert 'insuf_confs' not in headers, 'Server should acknowledge the created channel.'
    assert 'invalid_amount' not in headers, 'The correct amount should have been sent.'
    assert response.status_code == 200
    assert response.json() == 'success'
    assert len(server.resource_cache) == 1

    es_mock.search.assert_called_once_with(index='some_index',
                                           doc_type='some_type',
                                           body={'query': 'query something'})
Example #3
0
def test_dynamic_price(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                       client: Client, wait_for_blocks):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    price_cycle = cycle([1, 2, 3, 4, 5])
    url_to_price = {}  # type: Dict

    def price_fn(url: str):
        if url in url_to_price:
            price = url_to_price[url]
        else:
            price = next(price_cycle)
            url_to_price[url] = price
        return price

    proxy.add_paywalled_resource(DynamicPriceResource,
                                 '/resource_<int:res_id>', price_fn)

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    response = requests.get(endpoint_url + '/resource_5')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 2

    response = requests.get(endpoint_url + '/resource_2')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    channel = client.get_suitable_channel(headers.receiver_address, 2)
    wait_for_blocks(6)
    channel.update_balance(2)

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource_5', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == '5'
Example #4
0
def test_static_price(
        empty_proxy: PaywalledProxy,
        api_endpoint_address: str,
        client: Client,
        wait_for_blocks
):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(StaticPriceResource, '/resource', 3)

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == 'GET'

    assert_method(requests.post, endpoint_url + '/resource', headers, channel, 'POST')
    assert_method(requests.put, endpoint_url + '/resource', headers, channel, 'PUT')
    assert_method(requests.delete, endpoint_url + '/resource', headers, channel, 'DEL')
Example #5
0
def test_explicit_json(
        empty_proxy: PaywalledProxy,
        api_endpoint_address: str,
        client: Client,
        wait_for_blocks
):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(JSONResource, '/resource', 3)

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel = client.get_suitable_channel(headers.receiver_address, int(headers.price) * 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    # If headers don't merge properly, this results in 'application/json,application/json'.
    assert response.headers['Content-Type'] == 'application/json'
    assert response.json() == {'GET': 1}
Example #6
0
def test_static_price(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                      client: Client, wait_for_blocks, receiver_privkey: str):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    content = PaywalledContent(
        'resource',
        price=3,
        get_fn=lambda url: ('SUCCESS', 200),
    )
    proxy.add_content(content)

    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel = client.get_suitable_channel(headers.receiver_address, 3)
    wait_for_blocks(6)
    channel.balance = 3

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == '"SUCCESS"'

    close_channel_cooperatively(channel, receiver_privkey,
                                client.channel_manager_address, 0)
Example #7
0
def test_static_price(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                      client: Client, wait_for_blocks):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(StaticPriceResource, '/resource', 3)

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel = client.get_suitable_channel(headers.receiver_address,
                                          int(headers.price) * 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == 'GET'

    assert_method(requests.post, endpoint_url + '/resource', headers, channel,
                  'POST')
    assert_method(requests.put, endpoint_url + '/resource', headers, channel,
                  'PUT')
    assert_method(requests.delete, endpoint_url + '/resource', headers,
                  channel, 'DEL')
Example #8
0
def test_explicit_json(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                       client: Client, wait_for_blocks):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(JSONResource, '/resource', 3)

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel = client.get_suitable_channel(headers.receiver_address,
                                          int(headers.price) * 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    # If headers don't merge properly, this results in 'application/json,application/json'.
    assert response.headers['Content-Type'] == 'application/json'
    assert response.json() == {'GET': 1}
Example #9
0
def test_method_price(empty_proxy: PaywalledProxy, api_endpoint_address: str,
                      client: Client, wait_for_blocks):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(DynamicMethodResource,
                                 '/resource',
                                 resource_class_args=(42, ),
                                 resource_class_kwargs={'bar': 9814072356})

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    channel = client.get_suitable_channel(headers.receiver_address,
                                          1 + 2 + 3 + 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == 'GET'

    assert_method(requests.post,
                  endpoint_url + '/resource',
                  headers,
                  channel,
                  'POST',
                  expected_price=2)
    assert_method(requests.put,
                  endpoint_url + '/resource',
                  headers,
                  channel,
                  'PUT',
                  expected_price=3)
    assert_method(requests.delete,
                  endpoint_url + '/resource',
                  headers,
                  channel,
                  'DEL',
                  expected_price=4)
Example #10
0
def test_method_price(
        empty_proxy: PaywalledProxy,
        api_endpoint_address: str,
        client: Client,
        wait_for_blocks
):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    proxy.add_paywalled_resource(
        DynamicMethodResource,
        '/resource',
        resource_class_args=(42,),
        resource_class_kwargs={'bar': 9814072356})

    # test GET
    response = requests.get(endpoint_url + '/resource')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    channel = client.get_suitable_channel(headers.receiver_address, 1 + 2 + 3 + 4)
    wait_for_blocks(6)
    channel.update_balance(int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == 'GET'

    assert_method(requests.post,
                  endpoint_url + '/resource',
                  headers, channel, 'POST',
                  expected_price=2)
    assert_method(requests.put,
                  endpoint_url + '/resource',
                  headers, channel, 'PUT',
                  expected_price=3)
    assert_method(requests.delete,
                  endpoint_url + '/resource',
                  headers, channel, 'DEL',
                  expected_price=4)
Example #11
0
def assert_method(method, url, headers, channel, expected_reply, expected_price=3):
    # test POST
    response = method(url, headers=headers)
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == expected_price

    channel.update_balance(int(headers.sender_balance) + int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = method(url, headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == expected_reply
Example #12
0
def assert_method(method, url, headers, channel, expected_reply):
    # test POST
    response = method(url, headers=headers)
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    channel.update_balance(int(headers.sender_balance) + int(headers.price))

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = method(url, headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == expected_reply
Example #13
0
def test_dynamic_price(
        empty_proxy: PaywalledProxy,
        api_endpoint_address: str,
        client: Client,
        wait_for_blocks
):
    proxy = empty_proxy
    endpoint_url = "http://" + api_endpoint_address

    price_cycle = cycle([1, 2, 3, 4, 5])
    url_to_price = {}  # type: Dict

    def price_fn():
        url = request.path
        if int(url.split('_')[-1]) == 0:
            return 0
        if url in url_to_price:
            price = url_to_price[url]
        else:
            price = next(price_cycle)
            url_to_price[url] = price
        return price

    proxy.add_paywalled_resource(
        DynamicPriceResource,
        '/resource_<int:res_id>',
        price=price_fn
    )

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    response = requests.get(endpoint_url + '/resource_5')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 2

    response = requests.get(endpoint_url + '/resource_2')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 3

    response = requests.get(endpoint_url + '/resource_3')
    assert response.status_code == 402
    headers = HTTPHeaders.deserialize(response.headers)
    assert int(headers.price) == 1

    response = requests.get(endpoint_url + '/resource_0')
    assert response.status_code == 200
    assert response.text.strip() == '0'

    channel = client.get_suitable_channel(headers.receiver_address, 2)
    wait_for_blocks(6)
    channel.update_balance(2)

    headers = Munch()
    headers.balance = str(channel.balance)
    headers.balance_signature = encode_hex(channel.balance_sig)
    headers.sender_address = channel.sender
    headers.open_block = str(channel.block)
    headers = HTTPHeaders.serialize(headers)

    response = requests.get(endpoint_url + '/resource_5', headers=headers)
    assert response.status_code == 200
    assert response.text.strip() == '5'