Allow context to be specified as JSON and not base64 JSON.

Remove retrieve tests that utilize url parameters since it is a POST endpoint.
pull/2960/head
derekpierre 2022-08-30 18:40:10 -04:00 committed by Kieran Prasch
parent 67f4f50751
commit d77fac4d39
7 changed files with 30 additions and 59 deletions

View File

@ -674,9 +674,9 @@ Parameters
+-------------------------------------------+---------------+----------------------------------------+
| ``bob_verifying_key`` | String | Bob's verifying key encoded as hex. |
+-------------------------------------------+---------------+----------------------------------------+
| ``context`` *(Optional)* | String | | Associated data required during |
| ``context`` *(Optional)* | String | | Associated JSON data required during |
| | | | re-encryption e.g. data to satisfy |
| | | | conditions. |
| | | | re-encryption conditions. |
+-------------------------------------------+---------------+----------------------------------------+
@ -703,7 +703,7 @@ Parameters
because some Ursulas may have experienced a blip in connectivity. This is an optional optimization that provides
retry functionality that skips previously successful reencryption operations.
* A *context* is associated data required during re-encryption. One such example is when a condition for re-encryption
* A *context* is associated JSON data required during re-encryption. One such example is when a condition for re-encryption
requires proof of ownership of a wallet address; the *context* is used to provide the data and signature required for proof.

View File

@ -87,25 +87,20 @@ class Base64BytesRepresentation(BaseField, fields.Field):
raise InvalidInputData(f"Could not parse {self.name}: {e}")
class Base64JSON(Base64BytesRepresentation):
"""Serializes/Deserializes JSON objects as base64 byte representation."""
class JSON(BaseField, fields.Field):
"""Serializes/Deserializes objects to/from JSON strings."""
def _serialize(self, value, attr, obj, **kwargs):
try:
value_json = json.dumps(value)
return value_json
except Exception as e:
raise InvalidInputData(
f"Provided object type, {type(value)}, is not JSON serializable: {e}"
)
else:
json_base64_bytes = super()._serialize(
value_json.encode(), attr, obj, **kwargs
)
return json_base64_bytes
def _deserialize(self, value, attr, data, **kwargs):
json_bytes = super()._deserialize(value, attr, data, **kwargs)
try:
return json.loads(json_bytes)
result = json.loads(value)
return result
except Exception as e:
raise InvalidInputData(f"Invalid JSON bytes: {e}")
raise InvalidInputData(f"Invalid JSON: {e}")

View File

@ -160,7 +160,7 @@ class BobRetrieveCFrags(BaseSchema):
required=True))
# optional
context = base_fields.Base64JSON(
context = base_fields.JSON(
required=False,
load_only=True,
click=click.option(

View File

@ -18,15 +18,17 @@
import json
import os
from base64 import b64encode
from urllib.parse import urlencode
from nucypher_core import RetrievalKit
from nucypher.characters.lawful import Enrico
from nucypher.control.specifications.fields import Base64JSON
from nucypher.control.specifications.fields import JSON
from nucypher.crypto.powers import DecryptingPower
from nucypher.policy.kits import PolicyMessageKit, RetrievalResult
from nucypher.utilities.porter.control.specifications.fields import RetrievalResultSchema, RetrievalKit as RetrievalKitField
from nucypher.utilities.porter.control.specifications.fields import (
RetrievalResultSchema,
RetrievalKit as RetrievalKitField,
)
from tests.utils.middleware import MockRestMiddleware
from tests.utils.policy import retrieval_request_setup, retrieval_params_decode_from_rest
@ -173,7 +175,7 @@ def test_retrieve_cfrags(blockchain_porter,
#
# Use context
#
context_field = Base64JSON()
context_field = JSON()
multiple_retrieval_kits_params['context'] = context_field._serialize(random_context, attr=None, obj=None)
response = blockchain_porter_web_controller.post('/retrieve_cfrags', data=json.dumps(
@ -185,20 +187,6 @@ def test_retrieve_cfrags(blockchain_porter,
assert retrieval_results
assert len(retrieval_results) == 2
#
# Try same retrieval (with multiple retrieval kits) using query parameters
#
url_retrieve_params = dict(multiple_retrieval_kits_params) # use multiple kit params from above
# adjust parameter for url query parameter list format
url_retrieve_params['retrieval_kits'] = ",".join(url_retrieve_params['retrieval_kits']) # adjust for list
response = blockchain_porter_web_controller.post(f'/retrieve_cfrags'
f'?{urlencode(url_retrieve_params)}')
assert response.status_code == 200
response_data = json.loads(response.data)
retrieval_results = response_data['result']['retrieval_results']
assert retrieval_results
assert len(retrieval_results) == 2
#
# Failure
#

View File

@ -18,15 +18,17 @@
import json
from base64 import b64encode
from urllib.parse import urlencode
from nucypher_core import RetrievalKit
from nucypher.characters.lawful import Enrico
from nucypher.control.specifications.fields import Base64JSON
from nucypher.control.specifications.fields import JSON
from nucypher.crypto.powers import DecryptingPower
from nucypher.policy.kits import PolicyMessageKit, RetrievalResult
from nucypher.utilities.porter.control.specifications.fields import RetrievalResultSchema, RetrievalKit as RetrievalKitField
from nucypher.utilities.porter.control.specifications.fields import (
RetrievalResultSchema,
RetrievalKit as RetrievalKitField,
)
from tests.utils.policy import retrieval_request_setup, retrieval_params_decode_from_rest
@ -174,7 +176,7 @@ def test_retrieve_cfrags(federated_porter,
#
# Use context
#
context_field = Base64JSON()
context_field = JSON()
multiple_retrieval_kits_params['context'] = context_field._serialize(random_context, attr=None, obj=None)
response = federated_porter_web_controller.post('/retrieve_cfrags', data=json.dumps(multiple_retrieval_kits_params))
assert response.status_code == 200
@ -184,20 +186,6 @@ def test_retrieve_cfrags(federated_porter,
assert retrieval_results
assert len(retrieval_results) == 4
#
# Try same retrieval (with multiple retrieval kits) using query parameters
#
url_retrieve_params = dict(multiple_retrieval_kits_params) # use multiple kit params from above
# adjust parameter for url query parameter list format
url_retrieve_params['retrieval_kits'] = ",".join(url_retrieve_params['retrieval_kits'])
response = federated_porter_web_controller.post(f'/retrieve_cfrags'
f'?{urlencode(url_retrieve_params)}')
assert response.status_code == 200
response_data = json.loads(response.data)
retrieval_results = response_data['result']['retrieval_results']
assert retrieval_results
assert len(retrieval_results) == 4
#
# Failure
#

View File

@ -22,7 +22,7 @@ import pytest
from nucypher.control.specifications.exceptions import InvalidInputData
from nucypher.control.specifications.fields import (
Base64BytesRepresentation,
Base64JSON,
JSON,
PositiveInteger,
String,
StringList,
@ -74,7 +74,7 @@ def test_base64_representation_field():
field._deserialize(value=b"raw bytes with non base64 chars ?&^%", attr=None, data=None)
def test_base64_json_field():
def test_json_field():
# test data
dict_data = {
"domain": {"name": "tdec", "version": 1, "chainId": 1, "salt": "blahblahblah"},
@ -94,10 +94,10 @@ def test_base64_json_field():
# test serialization/deserialization of data
test_data = [dict_data, list_data, str_data, num_data, bool_data]
field = Base64JSON()
field = JSON()
for d in test_data:
serialized = field._serialize(value=d, attr=None, obj=None)
assert serialized == b64encode(json.dumps(d).encode()).decode()
assert serialized == json.dumps(d)
deserialized = field._deserialize(value=serialized, attr=None, data=None)
assert deserialized == d
@ -109,5 +109,5 @@ def test_base64_json_field():
with pytest.raises(InvalidInputData):
# attempt to deserialize invalid data
field._deserialize(
value=b"raw bytes with non base64 chars ?&^%", attr=None, data=None
value=b"raw bytes", attr=None, data=None
)

View File

@ -24,7 +24,7 @@ from nucypher_core import MessageKit, RetrievalKit
from nucypher.characters.control.specifications.fields import Key, TreasureMap
from nucypher.characters.lawful import Enrico
from nucypher.control.specifications.fields import Base64JSON
from nucypher.control.specifications.fields import JSON
from nucypher.crypto.powers import DecryptingPower
from nucypher.utilities.porter.control.specifications.fields import (
RetrievalKit as RetrievalKitField,
@ -76,7 +76,7 @@ def retrieval_request_setup(enacted_policy,
)
# context is optional
if context:
retrieval_params["context"] = encode_bytes(Base64JSON, context)
retrieval_params["context"] = encode_bytes(JSON, context)
return retrieval_params, message_kit
@ -98,7 +98,7 @@ def retrieval_params_decode_from_rest(retrieval_params: Dict) -> Dict:
# context is optional
if "context" in retrieval_params:
decoded_params["context"] = decode_bytes(
Base64JSON, retrieval_params["context"]
JSON, retrieval_params["context"]
)
return decoded_params